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


83

在C ++中,是这样的:

#ifdef A && B

与:

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

我当时以为不是,但是我没能找到与我的编译器(VS2005)不同的地方。



有人会引用并解释该标准,以决定该标准是否合法(它肯定不能起作用,但应该编译)吗?15分钟后,我无法阅读第16章“预处理指令”。
Ciro Santilli郝海东冠状病六四事件法轮功2015年

Answers:


91

他们不一样。第一个不起作用(我在gcc 4.4.1中进行了测试)。错误消息为:

test.cc:1:15:警告:#ifdef指令末尾的额外令牌

如果要检查是否定义了多个内容,请使用第二个。


感谢您的检查。我正在使用Microsoft的编译器,并且似乎允许使用它,但对我而言似乎并不正确。
criddell

2
您无法使用某些单个编译器来证明事物。请参阅标准,该标准指出这是无效的。
Lightness Races in Orbit

@LightnessRacesinOrbit但是,某些编译器扩展了该标准。说“它在特定的编译器中有效”并不是要证明它是有效的。注意到某个编译器以某种方式扩展了该标准。
基金莫妮卡的诉讼

@QPaysTaxes:同意,但是这个答案不行。它以“ C ++ ....”开头的一个问题开始,该问题似乎是关于C ++的普遍事实。乍一看,Evan用一个编译器测试了他的理论,然后通过语言本身的保证,认为它对所有人都是正确的。如果他确定此行为是GCC扩展,并说“这是GCC扩展”(带有参考资料的链接),那就可以了!(尽管不是对这个特定问题的真正答案)
Lightness Races in Orbit

1
虽然没有一些积极的测试可以“证明”,它有效的,单一的负足以证明它不是,或者说至少是不建议使用。尽管引用该标准会很好,但证明本标准至少在一个主要的编译器中不起作用,这足以证明在本讨论中“它不起作用”。
zeel

48

条件编译

您可以在#if指令中使用已定义的运算符,以使用在预处理程序行中计算为0或1的表达式。这样可以避免使用嵌套的预处理指令。标识符周围的括号是可选的。例如:

#if defined (MAX) && ! defined (MIN)  

如果不使用已定义的运算符,则必须包含以下两个指令才能执行上述示例:

#ifdef max 
#ifndef min

2
尽管您说的是正确的,但这根本无法回答问题,他问这两个是否相同……他们不是。
埃文·特兰

1
我认为它说的是“它们不相同”,您可以看到它解释了如何使#if define(COND_A)&& define(COND_B)等效于#ifdef COND_A && COND_B
Svetlozar Angelov

无论哪种方式,这都是一个有用的注释。
Paul Masri-Stone

2

以下结果是相同的:

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
您能否添加一些评论来描述这是如何回答问题的,从您的回答中还不清楚。
詹姆斯·伍德

从技术上讲,此答案虽然正确,但却无法准确回答问题,并暗示使用不正确。虽然这两个块将执行相同的操作,但嵌套两个ifs与使用&&不同。其他条件(例如)#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

为什么不只使用#elif而不是#else #if和结尾的十亿个#endif ...?
Elliott

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.