_Complex long int
TL;博士;
问: _Complex long int
中int
含义是什么? 为什么合法?
更长的版本
我将一些32位代码移植到64位安全。 在一个地方,我注意到它使用:
static __complex__ long int i32X[256];
转储搜索并替换为int32_t更改“long int”给了我一个编译错误。 complex是一个较旧的GNUism,由标准_Complex取代。这是一个重现问题的简短代码片段:
#include #include typedef _Complex long int WhyAmILegal; typedef _Complex int32_t Snafu; typedef int32_t _Complex Snafu2;
在gcc下编译给出:
complextest.c:6:26: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Snafu' typedef _Complex int32_t Snafu; ^~~~~ complextest.c:8:17: error: two or more data types in declaration specifiers typedef int32_t _Complex Snafu2;
(草案) C11标准说:
“有三种复杂类型,指定为float _Complex,double _Complex和long double _Complex.43”(复杂类型是实现不需要支持的条件特征;请参阅6.10.8.3。)实际的浮动和复杂类型统称为浮动类型。“
因此,当只有浮点复杂类型合法时,这里的错误似乎是我试图请求一个完整的复杂类型。 _Complex long
的含义实际上更像是_Complex long double
。 不过,我认为这可能是gcc解析器中的一个错误
_Complex long int
在网上也可以很好地编译。
那么为什么int ‘合法’在这里。
感谢@ Keith-Thompson指出,整数复数是GNU扩展,并且是clang支持的。
另一个数据点。 以下程序:
#include #include #include typedef _Complex long int ComplexLong; typedef _Complex short int ComplexShort; typedef _Complex int ComplexInt; int main(void) { fprintf(stderr,"sizeof(_Complex long int)=%d\n",sizeof(ComplexLong)); fprintf(stderr,"sizeof(_Complex int)=%d\n",sizeof(ComplexInt)); fprintf(stderr,"sizeof(_Complex short int)=%d\n",sizeof(ComplexShort)); fprintf(stderr,"sizeof(short int)=%d\n",sizeof(short int)); fprintf(stderr,"sizeof(int)=%d\n",sizeof(int)); fprintf(stderr,"sizeof(long int)=%d\n",sizeof(long int)); return 0; }
编译使用:
all: complextest complextest32 complextest: complextest.c $(CC) -o$@ $< complextest32: complextest.c $(CC) -m32 -o$@ $<
when(使用gcc编译)并运行时给出:
>./complextest sizeof(_Complex long int)=16 sizeof(_Complex int)=8 sizeof(_Complex short int)=4 sizeof(short int)=2 sizeof(int)=4 sizeof(long int)=8 >./complextest32 sizeof(_Complex long int)=8 sizeof(_Complex int)=8 sizeof(_Complex short int)=4 sizeof(short int)=2 sizeof(int)=4 sizeof(long int)=4
所以_Complex long int
like long
不能以体系结构不变的方式指定。 您应该使用_Complex int
或_Complex short
来稍微更_Complex short
。
这是一个gcc扩展,正如您可以通过编译(或多或少)符合C模式看到的:
$ cat cc _Complex double cd; _Complex long int cli; $ gcc -c cc $ gcc -c -std=c11 -pedantic cc cc:2:1: warning: ISO C does not support complex integer types [-Wpedantic] _Complex long int cli; ^~~~~~~~ $
这在gcc手册中有记录 :
ISO C99支持复杂的浮动数据类型,作为扩展,GCC在C90模式和C ++中支持它们。 GCC还支持复杂的整数数据类型,这些数据类型不属于ISO C99。
毋庸置疑,clang支持相同的扩展。
要回答添加的问题, _Complex
是一个类型说明符。 由于unsigned int32_t
无效, _Complex int32_t
无效。 类型说明符不能应用于typedef。