_复杂的long int [英] _Complex long int

查看:154
本文介绍了_复杂的long int的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

tl; dr;



Q int 中是什么意思_Complex long int ?为什么它是 legal?



更长版本



将某些32位代码移植为64位安全。
在一个地方,我注意到它使用了

 静态__complex__ long int i32X [256]; 

笨拙的搜索并替换为int32_t的 long int更改给了我一个编译错误。
__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:错误:在'Snafu'之前应为'=',',',';','asm'或'__attribute__'
typedef _Complex int32_t Snafu ;
^ ~~~~
complextest.c:8:17:错误:声明说明符中的两个或多个数据类型
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



也可以在在线铛下正常编译。 / p>

那么为什么 int 在这里合法。



感谢@ Keith-Thompson's指出整数复数是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));
返回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 cc 
_Complex double cd;
_Complex long int cli;
$ gcc -c cc
$ gcc -c -std = c11 -pedantic cc
cc:2:1:警告:ISO C不支持复杂的整数类型[-Wpedantic]
_Complex long int cli;
^ ~~~~~~~
$

这是记录在gcc手册中


ISO C99支持复杂的浮动数据类型,并且作为扩展GCC
在C90模式和C ++中支持它们。 GCC还支持不属于ISO C99的复杂
整数数据类型。


clang并不奇怪,支持相同的



要回答添加的问题, _Complex 是类型说明符。 _Complex int32_t 无效,原因与 unsigned int32_t 无效相同。类型说明符不能应用于typedef。


tl;dr;

Q what does int mean in _Complex long int? Why is it legal?

Longer version

I was porting some 32-bit code to be 64-bit safe. In one place I noted it uses:

static __complex__ long int i32X[256];

A dumb search and replace changing "long int" for int32_t gave me a compilation error. __complex__ is an older GNUism which has been replaced by the standard _Complex. Here is a short code snippet to reproduce the issue:

#include <complex.h>
#include <inttypes.h>

typedef _Complex long int WhyAmILegal;

typedef _Complex int32_t Snafu;

typedef int32_t _Complex Snafu2;

Compiled under gcc gives:

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;

The (draft) C11 standard says:

"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."

So the bug here would seem to be that I am trying to request an integral complex type when only floating point complex types are legal. The meaning of _Complex long is actually more like _Complex long double. I thought it might be a bug in gcc's parser, however

_Complex long int

compiles just fine under clang online as well.

So why is int 'legal' here.

Thanks to @Keith-Thompson's for pointing out that integral complex numbers are a GNU extension and one that is supported by clang.

Another data point. The following program:

#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;
}

Compiled using:

all: complextest complextest32

complextest: complextest.c
    $(CC) -o$@ $<

complextest32: complextest.c
    $(CC) -m32 -o$@ $<

when (compiled using gcc) and run gives:

>./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

So _Complex long int like long cannot be specified in an architecture invariant manner. You should use _Complex int or _Complex short to be slightly more portable.

解决方案

It's a gcc extension, as you can see by compiling in (more or less) conforming C mode:

$ 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;
 ^~~~~~~~
$

This is 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, not surprisingly, supports the same extension.

To answer the added question, _Complex is a type specifier. _Complex int32_t is invalid for the same reason unsigned int32_t is invalid. Type specifiers can't be applied to typedefs.

这篇关于_复杂的long int的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆