非指令是合法的预处理指令吗



c99标准几乎没有提到非指令,只是说它是"指令";,放在宏参数列表中是非法的(脚注150,附于6.10.3p11(。

人们会认为,这种定义的缺乏意味着任何非指令都会导致未定义的行为,并且应该作为错误报告,而gcc和clang大多都是这样。

然而,在这两个编译器中,行:

# 123 "filename"

相当于:

# line 123 "filename"

即使在设置了CCD_ 1标志时也是如此。

为什么会这样?我在网上只发现过一次提到它,但没有任何解决方案。

C 2018 6.10 9说:

执行非指令预处理指令会导致未定义的行为。

所以,是的,它是"合法的"(C标准不禁止您将其包含在程序中,也不禁止C实现定义行为(,但它的行为不是由C标准定义的。

C 1999标准中没有这一段,但该行为仍因遗漏而未定义(C 1999 4 2:"……未定义的行为在本国际标准中以"未定义行为"或遗漏任何明确的行为定义来表示……"(。

使用-std=c99不会自动拒绝C99标准中未指定的任何内容。如果需要,还可以添加-pedantic。这将为线路生成警告。

k.c:1:3: warning: style of line directive is a GCC extension
1 | # 123 "filename"
|   ^~~

https://linux.die.net/man/1/gcc

-迂腐的

发布严格的ISO C和ISO C++要求的所有警告;拒绝所有使用禁止扩展的程序,以及其他一些不遵循ISO C和ISO C++的程序。对于ISO C,遵循所使用的任何-std选项指定的ISO C标准版本。

但是,请注意:

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

在某些情况下,报告任何不符合ISO C的情况的功能可能很有用,但需要大量的额外工作,这与学究式的功能截然不同。我们没有计划在不久的将来支持这样的功能。

最新更新