_复杂的长整型
_Complex long int
tl;博士;
问int
在_Complex long int
中是什么意思?为什么它 合法?
更长的版本
我将一些 32 位代码移植到 64 位安全。
在一个地方我注意到它使用:
static __complex__ long int i32X[256];
愚蠢的搜索和替换更改 "long int" 为 int32_t 给了我一个编译错误。
__complex__ 是一个较旧的 GNUism,已被标准的 _Complex 取代。
这是重现问题的简短代码片段:
#include <complex.h>
#include <inttypes.h>
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 standard 说:
"共有三种复数类型,指定为float _Complex, double
_Complex, and long double _Complex.43)(复杂类型是有条件的
实现不需要支持的功能;见6.10.8.3。)真正的浮动类型和复杂类型统称为浮动类型。"
所以这里的错误似乎是我试图在只有浮点复杂类型合法时请求整数复杂类型。
_Complex long
的意思其实更像_Complex long double
。
我认为这可能是 gcc 解析器中的错误,但是
_Complex long int
在 clang online 下也能正常编译。
那为什么int 'legal'在这里。
感谢@Keith-Thompson 指出整数复数是一种 GNU 扩展,并且由 clang 支持。
另一个数据点。以下程序:
#include <complex.h>
#include <inttypes.h>
#include <stdio.h>
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$@ $<
当(使用 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
就像 long
不能以架构不变的方式指定。您应该使用 _Complex int
或 _Complex short
稍微更便携。
这是一个 gcc 扩展,您可以通过(或多或少)符合 C 模式的编译看到:
$ cat c.c
_Complex double cd;
_Complex long int cli;
$ gcc -c c.c
$ gcc -c -std=c11 -pedantic c.c
c.c:2:1: warning: ISO C does not support complex integer types [-Wpedantic]
_Complex long int cli;
^~~~~~~~
$
这是documented in the gcc manual:
ISO C99 supports complex floating data types, and as an extension GCC
supports them in C90 mode and in C++. GCC also supports complex
integer data types which are not part of ISO C99.
clang 毫不奇怪,支持相同的扩展。
要回答添加的问题,_Complex
是类型说明符。 _Complex int32_t
无效的原因与 unsigned int32_t
无效的原因相同。类型说明符不能应用于 typedef。
tl;博士;
问int
在_Complex long int
中是什么意思?为什么它 合法?
更长的版本
我将一些 32 位代码移植到 64 位安全。 在一个地方我注意到它使用:
static __complex__ long int i32X[256];
愚蠢的搜索和替换更改 "long int" 为 int32_t 给了我一个编译错误。 __complex__ 是一个较旧的 GNUism,已被标准的 _Complex 取代。 这是重现问题的简短代码片段:
#include <complex.h>
#include <inttypes.h>
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 standard 说:
"共有三种复数类型,指定为float _Complex, double _Complex, and long double _Complex.43)(复杂类型是有条件的 实现不需要支持的功能;见6.10.8.3。)真正的浮动类型和复杂类型统称为浮动类型。"
所以这里的错误似乎是我试图在只有浮点复杂类型合法时请求整数复杂类型。
_Complex long
的意思其实更像_Complex long double
。
我认为这可能是 gcc 解析器中的错误,但是
_Complex long int
在 clang online 下也能正常编译。
那为什么int 'legal'在这里。
感谢@Keith-Thompson 指出整数复数是一种 GNU 扩展,并且由 clang 支持。
另一个数据点。以下程序:
#include <complex.h>
#include <inttypes.h>
#include <stdio.h>
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$@ $<
当(使用 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
就像 long
不能以架构不变的方式指定。您应该使用 _Complex int
或 _Complex short
稍微更便携。
这是一个 gcc 扩展,您可以通过(或多或少)符合 C 模式的编译看到:
$ cat c.c
_Complex double cd;
_Complex long int cli;
$ gcc -c c.c
$ gcc -c -std=c11 -pedantic c.c
c.c:2:1: warning: ISO C does not support complex integer types [-Wpedantic]
_Complex long int cli;
^~~~~~~~
$
这是documented in the gcc manual:
ISO C99 supports complex floating data types, and as an extension GCC supports them in C90 mode and in C++. GCC also supports complex integer data types which are not part of ISO C99.
clang 毫不奇怪,支持相同的扩展。
要回答添加的问题,_Complex
是类型说明符。 _Complex int32_t
无效的原因与 unsigned int32_t
无效的原因相同。类型说明符不能应用于 typedef。