#ifdef中的布尔值: "#ifdef A && B"和"#if defined(A) && defined(B)"是否相同?

97

在C++中,这段代码:

#ifdef A && B

与之相同:

#if defined(A) && defined(B)

我一开始认为它不是不同的,但是我用我的编译器(VS2005)找不到区别。


1
可能是重复的问题:https://dev59.com/NnNA5IYBdhLWcg3wbNQ4 我看到它们是C和C++,但预处理器基本相同:https://dev59.com/0m445IYBdhLWcg3wAFm0 - Ciro Santilli OurBigBook.com
有人能引用并解释标准来确定它是否合法吗(它肯定不会起作用,但是它是否能编译)?我在阅读第16章“预处理指令”15分钟后还无法做到。 - Ciro Santilli OurBigBook.com
5个回答

102

它们不是相同的。第一个不起作用(我在gcc 4.4.1上测试过)。错误信息为:

test.cc:1:15: 警告: #ifdef 指令结尾处有额外的标记

如果您想检查多个变量是否已定义,请使用第二个。


感谢您的查看。我正在使用微软的编译器,它似乎允许这样做,但对我来说似乎并不正确。 - criddell
3
你不能仅凭一个编译器来证明事情。请参考标准,标准说明这是无效的。 - Lightness Races in Orbit
@LightnessRacesinOrbit 然而,一些编译器扩展了标准。说“它在某个编译器中工作”并不是试图证明它是有效的;它只是指出某个编译器以某种方式扩展了标准。 - anon
@QPaysTaxes:同意,但这个答案并没有做到这一点。它回答了一个以“在C++中……”开头的问题,似乎是关于C++的一个普遍事实。乍一看,Evan用一个编译器测试了他的理论,然后假设它对所有编译器都适用,因为语言本身保证了这一点。如果他确定这种行为是GCC扩展,并说“这是一个GCC扩展”(附带参考资料链接),那就可以了!(虽然不是这个特定问题的答案) - Lightness Races in Orbit
2
虽然没有任何数量的正面测试可以“证明”它是有效的,但单个负面测试就足以证明它无效,或者至少不建议使用。尽管参考标准很好,但证明它在至少一个主要编译器中无法工作足以证明“它不工作”用于本讨论的目的。 - zeel

52

条件编译

你可以在 #if 指令中使用 defined 运算符,以在预处理行内使用评估为 0 或 1 的表达式。这样可以避免使用嵌套的预处理指令。标识符周围的括号是可选的。例如:

#if defined (MAX) && ! defined (MIN)  
没有使用定义操作符,你需要包含以下两个指令来执行上面的示例:
#ifdef max 
#ifndef min

2
虽然你说的没错,但这并没有回答问题,他问的是这两个是否相同...它们不相同。 - Evan Teran
2
我认为它的意思是“它们不一样”,你可以看到它解释了如何制作与#ifdef COND_A && COND_B不同但等效于#if defined(COND_A) && defined(COND_B)的东西。 - Svetlozar Angelov
无论如何,这是一个有用的笔记。 - Paul Masri-Stone

4
以下结果相同:
1.
#define A
#define B
#if(defined A && defined B)
printf("define test");
#endif

2.

#ifdef A
#ifdef B
printf("define test");
#endif
#endif

1
你能否添加一些评论来描述如何回答这个问题,从你的回答中并不清楚。 - James Wood
这个答案在技术上是正确的,但并没有准确回答问题,并暗示了一种不正确的用法。虽然这两个代码块将执行相同的操作,但嵌套两个if语句并不等同于使用&&。其他条件,例如#else,可能会导致问题。只有第一个选项实际上完全符合提问者的要求。 - zeel

1

对于那些可能正在寻找与OP略有不同的示例(UNIX / g ++),这可能会有所帮助:

`

#if(defined A && defined B && defined C)
    const string foo = "xyz";
#else
#if(defined A && defined B)
    const string foo = "xy";
#else
#if(defined A && defined C)
    const string foo = "xz";
#else
#ifdef A
    const string foo = "x";
#endif
#endif
#endif
#endif

1
为什么不直接使用 #elif,而要使用 #else #if 和数十亿个 #endif 在最后呢? - Elliott

-3

在VS2015中,以上方法均不起作用。正确的指令是:

#if (MAX && !MIN)

查看更多这里


2
你链接到了C#文档,而不是C++的。 - Revolver_Ocelot

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