#ifdef带有多个标记,这样做合法吗?

6
今天我看到了一些包含以下 #ifdef 条件语句的C++代码:

#ifdef DISABLE_UNTIL OTHER_CODE_IS_READY
   foo();
#endif

请注意 "DISABLE_UNTIL" 和 "OTHER_CODE_IS_READY" 之间的空格。本质上,#ifdef 行中指定了两个标记。
我的问题是,这是合法的 C++ 代码吗?(g++ 编译它没有任何错误,它显然只忽略第二个标记)。如果合法,第二个标记是否应该有任何作用?

1
我尝试过的每个g++版本都会发出警告,从2.8.1到4.8.1,都会发出警告,要么是“warning: garbage at end of '#ifdef' argument”,要么是“warning: extra tokens at end of #ifdef directive”,或者是“warning: extra tokens at end of #ifdef directive [enabled by default]”。你怎么没有收到诊断信息呢? - Keith Thompson
@Keith:g++ myprogram.cpp -o myprogram | grep ! warning - Lightness Races in Orbit
@LightnessRacesinOrbit:这不会过滤警告(grep语法错误,gcc将诊断写入stderr)。无论如何,我认为你在猜测;我想知道OP是如何没有收到警告的。OP:您是否有意禁用警告? - Keith Thompson
@KeithThompson 我刚写了一个5行的测试程序,并使用以下命令进行编译:g++ temp.cpp(在MacOS/X 10.8.5下使用i686-apple-darwin11-llvm-g++-4.2)。 - Jeremy Friesner
什么5行程序?你是说没有警告吗? - Keith Thompson
显示剩余3条评论
2个回答

14

你发布的语法是非法的,并且意图不明确。

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

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

2
你非常出色地回答了其他问题。 - Lightness Races in Orbit
1
这句话怎么回答了“它是否合法”的问题? - P0W
我不确定代码的作者希望实现什么... 我怀疑这只是一个笔误(他错误地键入了一个空格而不是下划线)。 - Jeremy Friesner
+1 因为即使它没有回答“这是否合法?”部分的问题,我发现答案很有用。但是你认为这段代码有什么问题,导致你“拒绝接受它并视为不合适/无法使用”? - Daniel

6

[C++11 16.1], [C++11 16.5][C99 6.10.1/4]都表明这是无效的。

if-group:
# if constant-expression new-line groupopt
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt

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

GCC的官方文档也是这么说的

我的测试结果表明,只有第一个标识符被接受,第二个标识符被忽略;这可能是为了方便实现,但标准确实要求在此处发出诊断,因此您至少应该看到这个信息当您使用-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无论是否使用-pedantic选项,都会发出此警告


而标准并不要求在此处进行诊断” - 标准要求对语法规则的任何违反进行诊断。 - Keith Thompson
@Keith:哦,没错([C++11: 1.4/2])。我一直认为诊断是标准规则的默认选择,但事实上相反的情况更普遍。谢谢。 - Lightness Races in Orbit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接