不久前我发现了一个(相当古老的)C 编译器,它以这种方式扫描宏(伪代码):
if line.startswith("#include") or line.startswith("#define"):
...
.. 这给我提出了一个问题,宏应该真正放置在行的开头,如下所示:
void stuff()
{
#if defined(WIN32) || defined(_WIN32)
...
#else
#if defined(__GNUC__)
...
#else
...
#endif
#endif
}
或者像这样(因为这就是我这样做的方式,以提高可读性):
void stuff()
{
#if defined(WIN32) || defined(_WIN32)
...
#else
# if defined(__GNUC__)
...
# else
...
# endif
#endif
}
预处理器代码的缩进方式是否标准化,也就是说,无论我如何缩进,它总是以相同的方式工作?
一些旧的 C 编译器要求
#define
(例如)与左边距齐平:
#define FOO bar
其他 C 编译器仅要求
#
位于左边距,因此您可以:
# define FOO bar
较新的 C 编译器倾向于接受任何前导空格后的
#
:
#define FOO bar
如果您想与此类较旧的编译器兼容,您至少应该将
#
放在第一列中。如果兼容性不重要,那就取决于你了。
我通常会尝试不要在函数中嵌入
#ifdef
块,因此它们是否应该缩进的整个问题基本上就消失了。
来自 gcc C 预处理器文档:
预处理指令是以下行 您的程序以
#' 开头。#'. Whitespace is allowed before and after the
不,它们不需要位于行首,但前面只能有空格(空格、制表符……)。
通常将它们放在行首,因为它们不受其所属范围的限制,因为它们在实际 C 代码之前进行了预处理。
自标准的第一个版本(ANSI X3.159-1989 aka ANSI C 或 C89)以来,这已被明确允许。
参见第 3.8 节
预处理指令由一系列预处理标记组成,该序列以 # 预处理标记开头,该标记可以是源文件中的第一个字符(可以选择在不包含换行符的空格之后),也可以是在包含至少一个新行字符的空格之后-行字符,并以下一个换行符结束。[82]
还有脚注 82
因此,预处理指令通常称为“行”。这些“行”没有其他语法意义,因为除预处理期间的某些情况外,所有空格都是等效的(例如,请参见 3.8.3.2 中的 # 字符串文字创建运算符)。
没关系。这样看,如果代码未识别并且在 1 行中它仍然应该编译(只有代码、预处理器/包含其他一些东西需要单独的行)。
编辑:似乎真正老的编译器对此很挑剔。预处理器应该位于一行,就像其他非代码事物(例如 include)一样
我认为编译器不会“关心”预处理之前是否有空格 - 它应该是相同的......