96

In C++, is this:

#ifdef A && B

the same as:

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

?

I was thinking it wasn't, but I haven't been able to find a difference with my compiler (VS2005).

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
criddell
  • 14,289
  • 9
  • 41
  • 45
  • 1
    possible duplicate of: http://stackoverflow.com/questions/965700/c-preprocessor-testing-definedness-of-multiple-macros I see that they are C and C++, but the preprocessors are basically the same: http://stackoverflow.com/questions/5085533/is-a-c-preprocessor-identical-to-a-c-preprocessor – Ciro Santilli OurBigBook.com Apr 29 '15 at 10:43
  • Will someone quote and interpret the standard to decide if it is legal or not (it should not work for sure, but should it compile)? I'm unable to after 15 minutes of reading chap "16 Preprocessing directives". – Ciro Santilli OurBigBook.com Apr 29 '15 at 11:39

5 Answers5

101

They are not the same. The first one doesn't work (I tested in gcc 4.4.1). Error message was:

test.cc:1:15: warning: extra tokens at end of #ifdef directive

If you want to check if multiple things are defined, use the second one.

Evan Teran
  • 87,561
  • 32
  • 179
  • 238
  • Thanks for checking. I'm using Microsoft's compiler and it seems to allow it, but it just didn't seem right to me. – criddell Aug 21 '09 at 14:23
  • 3
    You cannot prove things using some single compiler. Refer to the standard, which states that this is invalid. – Lightness Races in Orbit Oct 11 '13 at 17:01
  • @LightnessRacesinOrbit However, some compilers extend the standard. Saying "it works in a certain compiler" isn't an attempt to prove it's valid; it's noting that a certain compiler extends the standard in a certain way. – Nic May 07 '16 at 23:20
  • @QPaysTaxes: Agreed, but this answer does not do that. It responds to a question that begins "in C++...." with what appears to be a general fact about C++. At first glance, Evan tested his theory with one compiler then assumed it's true for all, by way of a guarantee from the language itself. If he determined that this behaviour is a GCC extension and said "this is a GCC extension" (with link to reference material) then that would be okay! (albeit not really an answer to this particular question) – Lightness Races in Orbit May 07 '16 at 23:59
  • 2
    While no number of positive tests could "prove" that it *is* valid, a single negative is adequate to prove that it is not, or that it is at least not advisable to use. While referencing the standard would be nice, proving that it doesn't work in at least one major compiler is sufficient evidence to say "it doesn't work" for the purposes of this discussion. – zeel Oct 24 '18 at 16:33
52

Conditional Compilation

You can use the defined operator in the #if directive to use expressions that evaluate to 0 or 1 within a preprocessor line. This saves you from using nested preprocessing directives. The parentheses around the identifier are optional. For example:

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

Without using the defined operator, you would have to include the following two directives to perform the above example:

#ifdef max 
#ifndef min
Paul Masri-Stone
  • 2,843
  • 3
  • 29
  • 51
Svetlozar Angelov
  • 21,214
  • 6
  • 62
  • 67
4

The following results are the same:

1.

#define A
#define B
#if(defined A && defined B)
printf("define test");
#endif

2.

#ifdef A
#ifdef B
printf("define test");
#endif
#endif
jonspaceharper
  • 4,207
  • 2
  • 22
  • 42
way good
  • 59
  • 2
  • 1
    Can you please add some commentary to describe how this answers the question, its not clear from your answer. – James Wood Jul 20 '16 at 11:27
  • This answer, while technically correct, doesn't accurately answer the question, and implies an incorrect usage. While the two blocks will do the same thing, nesting two ifs is not the same as using &&. Other conditions, such as an `#else`, could cause a problem. Only the first option actually means exactly what the asker asked for. – zeel Oct 24 '18 at 16:29
1

For those that might be looking for example (UNIX/g++) that is a little different from the OP, this may help:

`

#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
MikeB
  • 21
  • 1
-3

As of VS2015 none of the above works. The correct directive is:

#if (MAX && !MIN)

see more here

Fabri
  • 1
  • 1