203

I am compiling my program that will run on linux gcc 4.4.1 C99.

I was just putting my #defines in to separate the code that will be compiled on either windows or linux. However, I got this error.

error: macro names must be identifiers.

Using this code

#ifdef(WIN32)
/* Do windows stuff */
#elif(UNIX)
/* Do linux stuff */
#endif

However, when I changed to this the error was fixed:

#if defined(WIN32)
/* Do windows stuff */
#elif(UNIX)
/* Do linux stuff */
#endif

Why did I get that error and why the #defines are different?

4 Answers 4

286

If you use #ifdef syntax, remove the parenthesis.

The difference between the two is that #ifdef can only use a single condition,
while #if defined(NAME) can do compound conditionals.

For example in your case:

#if defined(WIN32) && !defined(UNIX)
/* Do windows stuff */
#elif defined(UNIX) && !defined(WIN32)
/* Do linux stuff */
#else
/* Error, both can't be defined or undefined same time */
#endif
Sign up to request clarification or add additional context in comments.

4 Comments

yeah, but you could also cascade #ifdef UNIX with #ifndef WIN32, and get the same flexibility (not as readable, I agree)
@jpinto3912 But that gets even hairier with ||
If only they had just gone with #if defined(NAME) from the start and avoided creating an #ifdef statement.
Sourceforge has a good reference on pre-defined compiler macros.
81
#ifdef FOO

and

#if defined(FOO)

are the same,

but to do several things at once, you can use defined, like

#if defined(FOO) || defined(BAR)

Comments

37

#ifdef checks whether a macro by that name has been defined, #if evaluates the expression and checks for a true value

#define FOO 1
#define BAR 0

#ifdef FOO
#ifdef BAR
/* this will be compiled */
#endif
#endif

#if BAR
/* this won't */
#endif

#if FOO || BAR
/* this will */
#endif

3 Comments

This does not answer the question. The question asks for difference between #if defined and #ifdef.
This is the best explanation of how #if FOO and #if defined(FOO) can behave differently.
A useful answer since it shows the subtle difference between #ifdef and #if
1

With C23, you can use #elifdef and #elifndef:

#ifdef WIN32
/* Do windows stuff */
#elifdef UNIX
/* Do linux stuff */
#endif

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.