I am not a big fan of the C/C++ preprocessor directives
I am not denying that they certainly have their place and usage in the language.
I’ll first write about where I think they are useful and then about the situations
where I feel they are not.
#ifndef is very useful for preventing multiple
inclusions of a header which will cause redefinition errors.
#ifndef __FOO_H__ // only proceed if the token is not yet defined
#define __FOO_H__ // define the token so that subsequent includes have it defined
[...contents of the header...]
#endif // __FOO_H__, end for #ifndef statement
Of course, you can use
#pragma once to do the same thing, but that is a
Microsoft specific extension to the language so not everyone will use it. This
usage is error prone though. I can't count the number of times that I copied one
header to create another header in the same project and forgot to change the
#ifndef token to a new token and couldn't
figure out why my new header wasn't being evaluated properly.
#ifdef is useful in a header to switch between
ANSI and wide versions of the function, such as this example from
#define CreateFile CreateFileW
#define CreateFile CreateFileA
#endif // !UNICODE
Now, the reason I don't like these 2 directives is that they behave differently
#if token evaluates the value of
token is not defined, it defaults to zero and the
#if token phrases evaluates to zero. On the other hand,
#ifdef token evaluates to token to see if it is
defined, regardless of the value of
token. That means that the following code
#define FOO 0x0
will print out "FOO!" even though FOO evaluates to zero. As I have written previously
in my blog and in the newsgroups, I am big on maintainance of the code I write
because the code I write will have to be maintained for years and its connection
to me will eventually be lost by the developer who inherits it. What I don't like
in a source file (vs the header file examples above) is that at first glance, I
mentally evaluate a
and more often then not, pick the wrong result when reviewing the code. Furthermore,
everytime I see
I need to spend a minute or two staring at the entire statement to figure out
what is going on, it is not immediately apparent to me what it is doing. Anytime
I have to stare at something to figure out what it does, it is an indicator to me
that others will probably do the same and it will eventually be a problem spot
in the code in the future.
A lot of you may not agree with me and I am fine with that ;). Please let me
know why though.