Defining define

January 30, 2017

When I encounter a preprocessor branch in code I usually find myself struggling to recall the difference between #if, #ifdef, and #if defined. This post is an attempt to provide myself with a quick reference. Hopefully it might help others as well.

This chart summarizes things:

Checks for existence Numeric defines Supports && and || Supports ! No Yes Yes No Yes No No One condition (#ifndef) Yes No Yes Many conditions (!defined())

The details are below.

Start with #if

It produces a compiler error:

So to use #if, we need to have an actual value, like this.

Then a non-zero value will “activate” the branch.

It is also possible to use #if for logical conditions like && and ||.

Next up: #ifdef

Now let’s try #ifdef.

So just the presence of the defined value will activate this branch. We can comment it out to deactivate it.

We can use #ifndef to determine if a value is not defined.

Can we do Boolean operations, as with #if?

No, it seems Boolean conditions are not possible here. Even worse, we only get a warning, and the condition is evaluated as if the #ifdef is true! In this case, the actual behavior is the opposite of my intuition. This could be lost in a sea of warnings, and end up being difficult to track down.

In addition, numeric values are only checked for existence.

So maybe surprisingly, the behavior of #ifdef ZERO and #if ZERO are opposite.

Last but not least: #if defined

Finally, we can use the defined keyword, which something like a function call.

If the value is not defined, we get the other leg of the branch:

We can also check for a value that is not defined.

If addition, this syntax supports Boolean operators (&&, ||, and !):

The behavior of #if defined is the same as the behavior of #ifdef in this respect.