代码之家  ›  专栏  ›  技术社区  ›  Nick Van Brunt

注释是否总是在预处理器之前处理?[复制品]

  •  4
  • Nick Van Brunt  · 技术社区  · 15 年前

    这个问题已经有了答案:

    /*
    #define FOO
    */
    
    #ifdef FOO
    #define BAR "pirate"
    #else
    #define BAR "ninja"
    #endif
    
    int main() { printf(BAR); getchar(); }
    

    在此代码中未定义foo(Visual Studio 2008)。我假设先处理注释,然后是预处理器,然后是代码。注释是否总是在预处理器之前处理?这是标准的一部分吗?

    6 回复  |  直到 9 年前
        1
  •  9
  •   John Feminella    15 年前

    我假设先处理注释,然后是预处理器,然后是代码。注释是否总是在预处理器之前处理?

    有点--预处理器工作的一部分 删除注释。在这种情况下,您不关心注释中是否有该指令;它仍然像任何其他注释一样被删除。

        2
  •  10
  •   Alok Singhal    15 年前

    根据C标准,在程序的翻译(编译)过程中有8个翻译阶段。在翻译阶段3中,每个注释都被一个空白字符替换,而预处理指令在阶段4中执行。

        3
  •  7
  •   jamesdlin    15 年前

    是的,预处理器在处理指令之前替换注释。

    根据C99标准第5.1.1.2节(翻译阶段):

    3)源文件被分解为预处理标记和空白字符序列(包括注释)。每个注释都被一个空格字符替换….

    4)执行预处理指令,扩展宏调用,…

        4
  •  4
  •   AnT stands with Russia    15 年前

    是的,从语言标准的角度来看,处理注释(替换为空格) 之前 预处理器开始工作。

    在实际的实现中,注释的处理可以由处理预处理器指令并执行宏替换的相同代码(例如相同的可执行文件)完成,但结果必须相同:注释对预处理器没有适当的影响。

    在旧的和/或非标准代码中,有时可能会看到一些依赖于非标准行为的技巧,这些行为涉及实现特定的注释与预处理器关系,例如,使用预处理器指令创建注释。

    #define CONCAT(a, b) a##b
    #define BEGIN_COMMENT CONCAT(/, *)
    #define END_COMMENT CONCAT(*, /)
    
    BEGIN_COMMENT
      This code is supposedly commented-out
    END_COMMENT
    

    或者使用注释进行预处理器级连接(使用不支持的C编译器) ## 宏定义中的运算符)

    #define OLD_CONCAT(a, b) a/**/b
    

    这些技巧在标准C中都不是合法的,它们都不起作用。

        5
  •  3
  •   Sapph    15 年前

    一些快速的研究表明注释被转换为空白。 通过 预处理器。所以,这都是同一个流程的一部分。

    根据 Wikipedia ,在预处理器指令之前处理注释。

        6
  •  2
  •   Nifle Hassan Syed    15 年前

    是的(在每个健全的宇宙中)。