预处理器指令应该位于行首吗?

问题描述 投票:0回答:6

不久前我发现了一个(相当古老的)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++ c c-preprocessor
6个回答
20
投票

一些旧的 C 编译器要求

#define
(例如)与左边距齐平:

#define FOO bar

其他 C 编译器仅要求

#
位于左边距,因此您可以:

#    define FOO bar

较新的 C 编译器倾向于接受任何前导空格后的

#

    #define FOO bar

如果您想与此类较旧的编译器兼容,您至少应该将

#
放在第一列中。如果兼容性不重要,那就取决于你了。

我通常会尝试不要在函数中嵌入

#ifdef
块,因此它们是否应该缩进的整个问题基本上就消失了。


16
投票

来自 gcc C 预处理器文档

预处理指令是以下行 您的程序以

#'. Whitespace is allowed before and after the
#' 开头。


2
投票

不,它们不需要位于行首,但前面只能有空格(空格、制表符……)。

通常将它们放在行首,因为它们不受其所属范围的限制,因为它们在实际 C 代码之前进行了预处理。


0
投票

自标准的第一个版本(ANSI X3.159-1989 aka ANSI C 或 C89)以来,这已被明确允许。

参见第 3.8 节

预处理指令由一系列预处理标记组成,该序列以 # 预处理标记开头,该标记可以是源文件中的第一个字符(可以选择在不包含换行符的空格之后),也可以是在包含至少一个新行字符的空格之后-行字符,并以下一个换行符结束。[82]

还有脚注 82

因此,预处理指令通常称为“行”。这些“行”没有其他语法意义,因为除预处理期间的某些情况外,所有空格都是等效的(例如,请参见 3.8.3.2 中的 # 字符串文字创建运算符)。


-1
投票

没关系。这样看,如果代码未识别并且在 1 行中它仍然应该编译(只有代码、预处理器/包含其他一些东西需要单独的行)。

编辑:似乎真正老的编译器对此很挑剔。预处理器应该位于一行,就像其他非代码事物(例如 include)一样


-3
投票

我认为编译器不会“关心”预处理之前是否有空格 - 它应该是相同的......

© www.soinside.com 2019 - 2024. All rights reserved.