views:

194

answers:

4

What, if anything, is the difference between these directives?

#ifdef FOO

#if defined FOO

#if defined(FOO)

I'm using the CCS compiler, but I'm interested in other C compilers as well.

+1  A: 

#ifdef is short for #if defined and I think you don't need parenthesis on neither, so basically they are the same.

Coming from Turbo C, I'm used to looking at #ifdef rather than #if defined

Juparave
+8  A: 

From what I've seen, the main use for #if defined is to do a check for multiple macro definitions on one line. Otherwise, for single macro definition conditionals, they are identical as far as I know.

#include <stdio.h>
int main()
{
#if defined(FOO) && defined(BAR)
    printf("foobar!\n");
#else
    printf("nothing.\n");
#endif
    return 0;
}
$ tcc -DFOO -run a.c 
nothing.
$ tcc -DBAR -run a.c 
nothing.
$ tcc -DFOO -DBAR -run a.c 
foobar!

Also, the above program compiles fine with gcc -Wall -ansi a.c so that suggests #if defined is correct ANSI C. Moreover, this ANSI C summary from 1987 lists #if defined as newly defined behavior for the preprocessor under ANSI standards -- this should be standard across any ANSI-compliant compiler you will use.

If you weren't using #if defined, you'd have to do

#ifdef FOO
#ifdef BAR
    printf("foobar!\n");
#endif /* BAR */
#endif /* FOO */

Also, the Redhat manual for the C preprocessor says

#if defined MACRO is precisely equivalent to #ifdef MACRO.

Mark Rushakoff
Ah, I thought it might be something like that, and I was experimenting with it while you were answering. :-)
Jeanne Pindar
Also, I've found that #if !defined(FOO) is the same as #ifndef FOO
Jeanne Pindar
+3  A: 

All 3 forms are exactly equivalent and valid, according to the C99 standard. Generally #ifdef is preferred because it is shorter than the other two forms, but there are situations where you would want to use the other forms:

  • If testing for the definitions of multiple symbols, or more complex expressions:

    #if defined(ONE_THING) && define(ANOTHER_THING) && (3 < 4)
    ...
    #endif
    
  • If you have multiple clauses, it's much easier to use #elif defined(...) than #else, #ifdef:

    #if defined(ONE_THING)
    ...
    #elif defined(ANOTHER_THING)
    ...
    #elif defined(THIRD_THING)
    ...
    #else
    ...
    #endif
    

The usage of parentheses with defined is optional; I prefer using them to add clarity.

Adam Rosenfield
+1  A: 

Originally there was only #ifdef, but when #if came along it was necessay to have defined() in order for #if to superset #ifdef.

DigitalRoss