-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 的常量表达式初始化的,这段代码在“迂腐”模式下编译得很好。
- 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>
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 的常量表达式初始化的,这段代码在“迂腐”模式下编译得很好。
- 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
, andlong 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>