根据文档,我已阅读C99及更高版本支持float complex
,double complex
和long 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");
}
}
complex matrix[a][b];
给我们的是哪种类型?如果你用clang编译它,你会得到:
main.c:9:5:警告:简单&#39; _Complex&#39;需要一个类型说明符; 假设&#39; _Complex double&#39;
请参阅clang output。
gcc bug现已在this link报告。 (不是我。)
答案 0 :(得分:4)
根据C99(ISO 9899:1999):
complex
是一个宏(在<complex.h>
中定义),可扩展为_Complex
(7.3.1 / 2)。
_Complex
是类型说明符(就像int
,double
,unsigned
等)(6.7.2 / 1)。
6.7.2 / 2:
<强>约束强>
每个声明中的声明说明符中应至少提供一个类型说明符,并在每个结构声明和类型名称的说明符限定符列表中指定。每个类型说明符列表应为以下集合之一(用逗号分隔,当一行上有多个集合时);类型说明符可以按任何顺序出现,可能与其他声明说明符混合。
[...]
float _Complex
double _Complex
long double _Complex
这些是包含_Complex
的唯一类型说明符集,这意味着不允许complex
float
,double
或long double
。{ / p>
此外:
5.1.1.3诊断
1如果预处理翻译单元或翻译单元包含违反任何语法规则或约束的情况,符合要求的实现应生成至少一条诊断消息(以实现定义的方式标识),即使该行为也是明确的 指定为未定义或实现定义。
由于使用complex
all本身就是违反约束,因此需要编译器警告或错误。如果您没有收到gcc -std=c99 -pedantic
的警告,那么您在gcc中发现了一个错误。
答案 1 :(得分:3)
如果省略它,GCC和Clang看起来都假定类型为double
(如您的示例所示)。
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
^
虽然海湾合作委员会做同样的事情(假设为double
),但它似乎并不警告它。
无论编译器诊断如何,扩展到complex
的{{1}}本身不是类型,而只是类型说明符。因此,您需要指定类型。