https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html:
一些用户试图用它
-Wpedantic
来检查程序是否符合严格的 ISO C 标准。他们很快发现它并没有完全达到他们想要的效果:它找到了一些非 ISO 实践,但不是全部——只有那些 ISO C需要诊断的实践,以及已经添加了诊断的其他一些实践。
有哪些非 ISO 实践的例子,它们没有被-pedantic
?
https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html:
一些用户试图用它
-Wpedantic
来检查程序是否符合严格的 ISO C 标准。他们很快发现它并没有完全达到他们想要的效果:它找到了一些非 ISO 实践,但不是全部——只有那些 ISO C需要诊断的实践,以及已经添加了诊断的其他一些实践。
有哪些非 ISO 实践的例子,它们没有被-pedantic
?
这里的问题从根本上说是可能编写的 C 程序包含错误(不仅仅是未能实现严格的一致性),要求 C 编译器检测是不合理的。在最初编写标准时(1989 年),整个程序分析是不可能的,即使是现在,它也很昂贵。并且一个人将永远能够构建类似的结构
extern _Bool collatz_sequence_does_not_terminate(int);
int foo(int n) {
int rv;
if (collatz_sequence_does_not_terminate(n)) {
return rv;
}
return 23;
}
“这个程序是否有未定义的行为”的答案取决于一个解决方案未知的数学问题。
因此,手册试图警告您,不仅 GCC 无法检测到所有可能违反 ISO C 一致性的行为,而且没有编译器可以检测到。它的措辞有点过于珍贵,如果我仍然在 GCC 上工作,我可能会对其进行修改以使其更清晰。
如果你想要一个具体的例子来说明程序不符合标准,根本没有被诊断出来,并且在现实生活中相对可能出现,试试这个大小:
/* a.c */
#include <stdint.h>
uint64_t val = 0x0123456789abcdef;
/* b.c */
#include <stdio.h>
extern double val;
int main(void) {
printf("%g\n", val);
return 0;
}
需要全程序分析来检测两个文件之间的类型不匹配。这不是一个困难的案例。编译器可以用它的类型注释每个全局符号,链接器可以检查每个符号的所有使用情况是否与定义保持一致。但我不知道有任何工具链或任何静态分析产品会检测到此变量错误。
GCC 支持 ISO C 不需要的其他形式的常量表达式。例如:
int main() {
const int m = 5;
static int n = m;
return n;
}
这段代码在“迂腐”模式下编译得很好,即使static
变量是用不符合 ISO C 的常量表达式初始化的。
GCC 允许标识符中的“$”字符作为大多数目标的扩展。无论 std= 开关如何,这都是正确的,因为此扩展不能与符合标准的程序冲突。但是,在预处理汇编程序时,默认情况下美元不是标识符字符。
UPD。2.允许“平原complex
”:
#include <complex.h>
complex x;
$ gcc -std=c11 -pedantic -Wall -Wextra
<nothing>
C11,6.2.5 类型,11:
共有三种复杂类型,分别指定为
float _Complex
、double _Complex
和long double _Complex
。
和 7.3.1 介绍,4:
宏
complex
扩展为_Complex
;