显然,让编译器遇到@
字符会导致语法错误(除非它是注释或字符串文字)。但是,如果找到该字符,例如在#if 0
块内,该程序在技术上是否有效?
我试过了:
#define NOTHING(x)
int main()
{
NOTHING(@@@@);
return 0;
}
使用-pedantic -Wall -Wextra
同时使用gcc和clang并且它没有发出警告。我不确定这是否有效,或者他们是否只是没有特定的警告。
我没有在标准中找到任何说法,但这令人担忧。我不想在此基础上建立一个工具,只是为了发现符合标准的编译器会对它产生阻塞。
答案 0 :(得分:9)
只要预编程器将其删除或字符串化,您几乎可以在C程序中包含任何字符。 @是一个有效的预处理程序标记,因此在编译的预处理阶段不会将其标记为错误。
该标准不会阻止编译器发出有关任何内容的警告,并且在这种情况下编译器可能会产生警告。但我不知道哪一个做了,我认为这是一个实施质量问题。
相关标准部分:
第6.4节中预处理令牌的定义:“不能是上述之一的每个非空白字符”。请注意,@@@@
因此是四个预处理令牌。
§6.4/ 2,强调添加:“转换为令牌的每个预处理令牌应具有关键字的词法形式,标识符,常量,字符串文字,或者是一个标点符号。“只要@
未“转换为令牌”,就不会发生错误。转换为令牌发生在编译过程的第7阶段(参见§5.1.1.2/ 7)。在第4阶段扩展宏(包括字符串化)之后很久。