【问题标题】:Should preprocessor instructions be on the beginning of a line?预处理器指令应该在行首吗?
【发布时间】:2011-01-18 08:38:22
【问题描述】:

不久前,我发现了一个(相当古老的)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
}

Preprocessor 代码的缩进方式是否标准化,也就是说,无论我如何缩进它,它总是以相同的方式工作?

【问题讨论】:

  • 喜欢伪代码:D。 “伪代码”是一门很棒的语言。

标签: c++ c c-preprocessor


【解决方案1】:

一些旧的 C 编译器要求 #define(例如)与左边距齐平:

#define FOO bar

其他 C 编译器只要求 # 位于左边距,因此您可以:

#    define FOO bar

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

    #define FOO bar

如果您想与此类较旧的编译器兼容,您至少应该将# 放在第一列。如果兼容性无关紧要,那就看你自己了。

我通常会尽量不将 #ifdef 块嵌入函数中,因此它们是否应该缩进的整个问题大部分都消失了。

【讨论】:

  • 我想我不必担心对 ZetaC 等编译器的支持,幸运的是,这些编译器已经很少使用了 ;-)
  • “如果你想与这些旧的编译器兼容”——那么你需要找出他们甚至没有实现 C89 的地方,更不用说 C99 了?
  • 你说的是 ANSI K&R v1 之前的编译器。所以忘记函数声明和参数列表吧。
【解决方案2】:

来自gcc C preprocessor documentation:

预处理指令是 以#'. Whitespace is allowed before and after the#' 开头的程序。

【讨论】:

  • @Will:你可能在我在引文中添加第二句话之前写了这个评论:)
【解决方案3】:

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

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

【讨论】:

  • # 后面允许有空格,如`#include `
  • @peoro 我猜“他们之前只能有空格”是模棱两可的 - 即它可能意味着“他们可以在他们之前有空格,但不能在其他任何地方”或者它可能意味着“在他们之前他们只能有空格,不能有其他”。当然你的意思是后者,但措辞是模棱两可的。
【解决方案4】:

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

编辑:似乎真的老编译器对此很挑剔。预处理器应该在一行,就像其他非代码的东西一样包含

【讨论】:

  • 如果代码没有全部缩进一行,它将无法编译:预处理器是行敏感的。
  • 是的,忘记了那部分。预处理器需要在 1 行(没有其他任何内容),但对于代码来说这并不重要。
【解决方案5】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多