【发布时间】:2015-03-08 09:28:51
【问题描述】:
我已经编写 C 语言有一段时间了。在此期间,我了解到将预处理器指令之前的“#”字符放在第一列是一种常见的约定。
例子:
#include <stdio.h>
int main(void) {
#ifdef MACRO1
#ifdef MACRO2
puts("defined(MACRO1) && defined(MACRO2)");
#else
puts("defined(MACRO1)");
#endif
#else
puts("!defined(MACRO1)");
#endif
return 0;
}
当人们缩进他们的预处理器指令时,他们通常会这样做:
#include <stdio.h>
int main(void) {
#ifdef MACRO1
# ifdef MACRO2
puts("defined(MACRO1) && defined(MACRO2)");
# else
puts("defined(MACRO1)");
# endif
#else
puts("!defined(MACRO1)");
#endif
return 0;
}
我认为我从未见过有人这样格式化它:
#include <stdio.h>
int main(void) {
#ifdef MACRO1
#ifdef MACRO2
puts("defined(MACRO1) && defined(MACRO2)");
#else
puts("defined(MACRO1)");
#endif
#else
puts("!defined(MACRO1)");
#endif
return 0;
}
我的问题是 C 语言标准是否要求#-字符应位于第一列。
那么上面的第三个选项是否合法?
如果以上所有情况都是合法的,那么我想知道这是否合法。
#include <stdio.h>
int main(void) {
#ifdef MACRO
puts("defined(MACRO)");
/* Now there are other characters before the `#` */ #endif
return 0;
}
这里是 #endif 不再在行的“开始”,因为还有其他非空白字符。
最后一个例子的奇怪之处在于Vim text-editor 没有突出显示评论后的#endif。
我给出的所有这些示例都使用gcc 并打开-Wall -pedantic 标志(包括#endif 之前带有注释的最后一个)进行编译,没有任何警告。
请注意,我只是对语法感到好奇。当我编程时,我总是像其他人一样将#-character 放在第一列。在严肃的项目中,我永远不会写 ++i; #endif 这样的东西。
【问题讨论】:
-
我一直缩进预处理器指令。但我从来没有在
#和指令名称之间放置空格,我总是确保附加了#和指令名称,而是在#前面放置空格。它工作正常。 -
@user3629249 我不同意:这是一个典型的语言律师问题,无法通过使用编译器检查编译来回答。这种问题必须引用标准来回答。可惜,问题已经有五个标签了,否则我会添加语言律师标签...
-
@user3629249 这不是投反对票的好理由,我赞成它,因为即使编译器接受它并不意味着所有编译器都会接受。您必须在此处引用标准。
-
我将您的
c-preprocessor标记换成了language-lawyer,因为您正在询问有关标准的具体问题。c和preprocessor这对应该足够了,添加的标签可能会减少反对和/或投票结束的倾向。如果您反对更改,请随时回滚。 -
@MartinJames:测试您的特定编译器是否允许缩进指令很容易。问题是语言标准保证了什么。
标签: c syntax language-lawyer c-preprocessor conditional-compilation