2017-10-21 63 views
3

为什么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 
+0

您确定在C99模式('-std = c99')下运行时会接受'short int complex'吗?考虑提高警告水平。 – alk

+0

@alk是的。即使有'--pedantic'和'-Wall -Werror' –

回答

6

首先,复数整数类型是GCC扩展。 C标准说(C11 6.2.5p11):

11 There are three complex types, designated as float _Complex , double _Complex , and long 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一个typedeflong double!同样,定义复杂类型时不能使用typedef(如int16_t),请改为使用short int _Complex

(这当然也适用于complex,因为它只是一个扩展到_Complex的宏)。

3

很简单,因为有没有这样的类型,如int16_t complex。 C11中的有效复杂类型为float complex,double complexlong double complex

complex是一个宏which expands to _Complex它是实际的类型说明符。

+0

那么为什么'short int complex'和'int complex'工作? –

+4

GCC支持[复杂整数类型](https://gcc.gnu.org/onlinedocs/gcc/Complex.html)作为扩展名,它们是非标准的。 –

4

这是因为_Complex是类型名称本身的一部分,而不是可以与其他类型一起使用的修饰符。它不适用于任何类型的typedefs,不仅仅是short。例如,如果你这样做

typedef float fp32; 
fp32 _Complex x = I + I/3 * I/2; 

你会看到相同的编译错误。

+0

这很有趣。这种间隔关键字的概念是否受C++/CLI的启发? – IllidanS4

+0

@ IllidanS4曾听说过'unsigned char' ...这是** C **。 –

+0

@AnttiHaapala但'unsigned'是一个关键字,不是吗?据说它是许多地方的修饰语。 – IllidanS4