C语言中“复杂”的默认类型

ele*_*ora 5 c gcc

根据该文档我读C99及更高版本支持float complexdouble complexlong double complex为复杂类型。但是,使用时,此代码会编译而不会发出警告gcc -Wall -Wextra

#include <stdio.h>
#include <complex.h>

int main() {
    int a, b, c, d;
    float re, im;

    scanf("%d %d", &a, &b);
    complex matrix[a][b]; /* <------ */

    for(c=0; c<a; c++) {
        for(d=0; d<b; d++) {
            scanf("%f%fi", &re, &im);
            matrix[c][d] = re + im * I;
        }
    }

    for(c=0; c<a; c++) {
        for(d=0; d<b; d++) {
            printf("%.2f%+.2fi ", creal(matrix[c][d]), cimag(matrix[c][d]));
        }
        printf("\n");
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 这是有效的C还是gcc的奇数?
  • 什么类型complex matrix[a][b];给我们?

如果使用clang进行编译,则会得到:

main.c:9:5:警告:普通的'_Complex'需要类型说明符;假设为“ _Complex double”

请参阅clang输出


现在在此链接报告了gcc错误。(不是我的。)

mel*_*ene 5

根据C99(ISO 9899:1999):

  • complex是一个宏(在中定义<complex.h>),扩展为_Complex(7.3.1 / 2)。

  • _Complex是一种类型的说明符(就像intdoubleunsigned等)(6.7.2 / 1)。

6.7.2 / 2:

约束条件

在每个声明的声明说明符中,以及在每个struct声明和类型名称的说明符限定符列表中,至少应提供一个类型说明符。类型说明符的每个列表应为以下集合之一(当一行上有多个集合时,以逗号分隔);类型说明符可以以任何顺序出现,并且可能与其他声明说明符混合使用。

  • [...]

  • float _Complex

  • double _Complex
  • long double _Complex

这些是包含唯一类型说明符集_Complex,这意味着complex没有floatdouble或者long double是不允许的。

此外:

5.1.1.3诊断

1如果预处理翻译单元或翻译单元包含违反任何语法规则或约束的条件,即使该行为也被明确指定为未定义或实现,则符合标准的实现应产生至少一个诊断消息(以实现定义的方式标识) -定义。

由于单独使用complex全部都是违反约束的,因此需要编译器警告或错误。如果您没有收到的警告gcc -std=c99 -pedantic,则说明您在gcc中发现了一个错误。


P.P*_*.P. 4

double如果您省略它(如您的示例中所示),看起来 GCC 和 Clang 都会假定该类型。Clang 产生:

 warning: plain '_Complex' requires a type specifier; assuming '_Complex double'
    complex matrix[a][b];
    ^
            double
/usr/include/complex.h:39:18: note: expanded from macro 'complex'
#define complex         _Complex
                        ^
Run Code Online (Sandbox Code Playgroud)

虽然 GCC 也做了同样的事情(假设double),但它似乎没有警告它。

无论编译器诊断如何,complex它扩展为本身_Complex并不是一个类型,而只是一个类型说明符。因此,您需要指定类型。

  • `double` 也是一个*类型说明符*。 (2认同)