#ifdef有多个令牌,这是合法的吗?

时间:2013-10-11 15:32:16

标签: c++ c-preprocessor language-lawyer conditional-compilation

今天我遇到了一些包含#ifdef子句的C ++代码:

#ifdef DISABLE_UNTIL OTHER_CODE_IS_READY
   foo();
#endif

请注意“DISABLE_UNTIL”和“OTHER_CODE_IS_READY”之间的空格。基本上#ifdef行中指定了两个标记。

我的问题是,这是合法的C ++代码吗? (g ++编译它没有任何错误,它显然只是忽略了第二个标记)。如果它是合法的,第二个令牌是否会产生任何影响?

2 个答案:

答案 0 :(得分:11)

您发布的语法不合法,其含义不明确。

根据您希望实现的目标,您可以使用||&&进行组合吗? (当然,如果这是别人的代码,我会拒绝将其视为不适当/无法使用)

#if defined(DISABLE_UNTIL) || defined(OTHER_CODE_IS_READY)
    foo();
#endif

答案 1 :(得分:6)

[C++11 16.1][C++11 16.5],顺便提一句,[C99 6.10.1/4]都说这是无效的。

  

如果基团
  # if 常量表达式 换行 opt
  # ifdef 标识符 新行 opt
  # ifndef 标识符 换行 opt

只有一个标识符是合法的。

海湾合作委员会自己的文件agrees

My own tests表示只接受第一个标识符,而第二个标识符被简单地丢弃;这可能是为了简化实现,但标准确实需要在这里进行诊断,因此当您使用-pedantic标志至少时应该看到这一点。

#include <iostream>
using namespace std;

#define A
#define B

int main() {
    #ifdef A
    std::cout << "a ";
    #endif

    #ifdef B
    std::cout << "b ";
    #endif

    #ifdef C
    std::cout << "c ";
    #endif

    #ifdef B C
    std::cout << "bc ";
    #endif

    #ifdef C B
    std::cout << "cb ";
    #endif

    return 0;
}

// Output: "a b bc"
// Note: "cb" *not* output

Coliru的GCC安装发出with or without -pedantic