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

Is the non-directive a legal c preprocesing directive?

The c99 standard 几乎没有说明非指令 - 只是说它是“指令”,因为放在宏参数列表中是非法的(脚注 150,附于 6.10.3p11) .

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

但是,在两个编译器中,行:

# 123 "filename"

相当于:

# line 123 "filename"

即使设置了 -std=c99 标志。

为什么会这样?我只找到a single mention of it online,没有解决。

C 2018 6.10 9 说:

The execution of a non-directive preprocessing directive results in undefined behavior.

所以,是的,它是“合法的”(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

-pedantic

Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++. For ISO C, follows the version of the ISO C standard specified by any -std option used.

但是,请注意:

Some users try to use -pedantic 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.

A feature to report any failure to conform to ISO C might be useful in some instances, but would require considerable additional work and would be quite different from -pedantic. We don't have plans to support such a feature in the near future.