5

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

一些用户试图用它-Wpedantic来检查程序是否符合严格的 ISO C 标准。他们很快发现它并没有完全达到他们想要的效果:它找到了一些非 ISO 实践,但不是全部——只有那些 ISO C需要诊断的实践,以及已经添加了诊断的其他一些实践。

有哪些非 ISO 实践的例子,它们没有被-pedantic?

4

3 回答 3

3

这里的问题从根本上说是可能编写的 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;
}

需要全程序分析来检测两个文件之间的类型不匹配。这不是一个困难的案例。编译器可以用它的类型注释每个全局符号,链接器可以检查每个符号的所有使用情况是否与定义保持一致。但我不知道有任何工具链或任何静态分析产品检测到此变量错误。

于 2021-11-02T21:23:08.927 回答
2

GCC 支持 ISO C 不需要的其他形式的常量表达式。例如:

int main() {
  const int m = 5;
  static int n = m;
  return n;
}

这段代码在“迂腐”模式下编译得很好,即使static变量是用不符合 ISO C 的常量表达式初始化的。

于 2021-11-03T08:44:42.797 回答
0
  1. C 预处理器,11.1实现定义的行为

GCC 允许标识符中的“$”字符作为大多数目标的扩展。无论 std= 开关如何,这都是正确的,因为此扩展不能与符合标准的程序冲突。但是,在预处理汇编程序时,默认情况下美元不是标识符字符。

UPD。2.允许“平原complex”:

#include <complex.h>
complex x;

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

C11,6.2.5 类型,11:

共有三种复杂类型,分别指定为float _Complexdouble _Complexlong double _Complex

和 7.3.1 介绍,4:

complex扩展为_Complex;

于 2022-02-01T20:46:42.433 回答