_Complex long int

时间:2017-09-24 22:27:09

标签: c 32bit-64bit complex-numbers

TL;博士;

int _Complex long int的含义是什么?为什么合法?

更长的版本

我将一些32位代码移植到64位安全。 在我注意到的一个地方使用:

static __complex__ long int i32X[256];

愚蠢的搜索和替换更改" long int" for 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说:

&#34;有三种复杂类型,指定为float _Complex,double _Complex和long double _Complex.43)(复杂类型是有条件的 实现不需要支持的功能;见6.10.8.3。)真正的浮动和复杂类型统称为浮动类型。&#34;

因此,当只有浮点复杂类型合法时,这里的错误似乎是我试图请求一个完整的复杂类型。 _Complex long的含义实际上更像_Complex long double。 我认为它可能是gcc解析器中的一个错误,但

_Complex long int

clang online下也可以很好地编译。

那么为什么 int &#39; legal&#39;这里。

感谢@ 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$@ $<

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之类的long无法以体系结构不变的方式指定。您应该使用_Complex int_Complex short稍微便携一些。

1 个答案:

答案 0 :(得分:3)

这是一个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支持复杂的浮动数据类型,并作为扩展GCC   在C90模式和C ++中支持它们。 GCC也支持复杂   整数数据类型,不属于ISO C99。

clang,毫不奇怪,支持相同的扩展。

要回答添加的问题,_Complex是一个类型说明符。 _Complex int32_tunsigned int32_t无效的原因transfer.txt无效。类型说明符不能应用于typedef。