-pedantic 找不到的非 ISO 实践的例子有哪些?

What are the examples of non-ISO practices, which are not found by -pedantic?

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html :

Some users try to use -Wpedantic to check programs for strict ISO C conformance. They soon find that it does not do quite what they want: it finds some non-ISO practices, but not all—only those for which ISO C requires a diagnostic, and some others for which diagnostics have been added.

-pedantic没有找到的非ISO做法的例子有哪些?

这里的问题从根本上讲是可能编写包含错误(不仅仅是未能实现严格一致性)的 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 的常量表达式初始化的,这段代码在“迂腐”模式下编译得很好。

  1. C 预处理器,11.1 Implementation-defined behavior:

GCC allows the ‘$’ character in identifiers as an extension for most targets. This is true regardless of the std= switch, since this extension cannot conflict with standards-conforming programs. When preprocessing assembler, however, dollars are not identifier characters by default.

更新。 2.允许“普通complex”:

#include <complex.h>
complex x;

$ gcc t0.c -std=c11 -pedantic -Wall -Wextra
<nothing>

C11, 6.2.5 类型, 11:

There are three complex types, designated as float _Complex, double _Complex, and long double _Complex.

和 7.3.1 简介,4:

The macro complex expands to _Complex;

更新。 3. __has_attribute:

#if __has_attribute(xxx)
#endif
int x;

$ gcc t0.c -std=c11 -pedantic -Wall -Wextra
<nothing>