为什么'int16_t complex'不起作用?
为什么int16_t complex
不能编译,而在x86和x86_64机器上的int16_t
,是short int
上的typedef?以下是使用C99和C11标准对gcc 5.4和4.9进行测试的示例代码。编译器抱怨在声明说明符中有两个或多个数据类型。为什么'int16_t complex'不起作用?
代码:
#include <complex.h>
#include <stdint.h>
#include <stdio.h>
int main()
{
float complex x = I + I/3 * I/2;
short int complex y = I + I/3 * I/2;
int16_t complex z = I + I/3 * I/2; /* Why ? */
printf("x=(%+f,%+f)\n", creal(x), cimag(x));
printf("y=(%+f,%+f)\n", creal(y), cimag(y));
printf("z=(%+f,%+f)\n", creal(z), cimag(z)); /* Why ? */
return 0;
}
错误:
In file included from ./complex.c:1:0:
./complex.c: In function ‘main’:
./complex.c:9:13: error: two or more data types in declaration specifiers
int16_t complex z = I + I/3 * I/2; /* Why ? */
编译器命令行:
gcc-5 --std=c99 ./complex.c -o ./complex
gcc-4.9 --std=c99 ./complex.c -o ./complex
首先,复数整数类型是GCC扩展。 C标准说(C11 6.2.5p11):
11 There are three complex types, designated as
float _Complex
,double _Complex
, andlong double _Complex
.43) (Complex types are a conditional feature that implementations need not support; see 6.10.8.3.) The real floating and complex types are collectively called the floating types.
的_Complex
是类型名称的一部分,就像long
。你不能做到这一点无论:
typedef double dbl;
typedef long dbl ldbl;
即尝试使用一个typedef双时定义ldbl
一个typedef
为long double
!同样,定义复杂类型时不能使用typedef
(如int16_t
),请改为使用short int _Complex
。
(这当然也适用于complex
,因为它只是一个扩展到_Complex
的宏)。
很简单,因为有没有这样的类型,如int16_t complex
。 C11中的有效复杂类型为float complex
,double complex
和long double complex
。
complex
是一个宏which expands to _Complex
它是实际的类型说明符。
那么为什么'short int complex'和'int complex'工作? –
GCC支持[复杂整数类型](https://gcc.gnu.org/onlinedocs/gcc/Complex.html)作为扩展名,它们是非标准的。 –
这是因为_Complex
是类型名称本身的一部分,而不是可以与其他类型一起使用的修饰符。它不适用于任何类型的typedefs,不仅仅是short
。例如,如果你这样做
typedef float fp32;
fp32 _Complex x = I + I/3 * I/2;
你会看到相同的编译错误。
您确定在C99模式('-std = c99')下运行时会接受'short int complex'吗?考虑提高警告水平。 – alk
@alk是的。即使有'--pedantic'和'-Wall -Werror' –