Why do people use #ifdef for feature flag tests? Why do people use #ifdef for feature flag tests? c c

Why do people use #ifdef for feature flag tests?


Why do people still use #ifdef in this scenario?

Personal opinion: it's marginally easier to control from the command line. I prefer -DOPTION over -DOPTION=1.

Also, existence of a name is clearly binary. I don't have to be able to handle {0, non-zero, undefined}.

Are they simply unaware that #if works perfectly fine on undefined names?

I wasn't aware. What are the semantics of this? Is an undefined name assumed to be 0? Do I want to have to explain that to the guy who barely understands the preprocessor to begin with?

Or is there an actual disadvantage to #if vs #ifdef for conditional compilation?

To me, the binary nature of #ifdef/#ifndef of name existence is a clarity benefit.Also, my primary usage of either construct is for include guards. That pattern is cleanest with #ifndef.


I cannot speak to why people in general prefer #ifdef over #if, but I can at least say why I do. Based on introspection just now (since you asked -- I've never considered it explicitly before), there are 2 reasons:

1) I prefer my macros (which I try to use sparingly) to have the most straightforward semantics as possible, and correspondingly as "type free" as possible. I assume that macros, if they have any type at all, are either "type free functions" (note: here I would strongly prefer templates, but there are times for everything...) or basically just boolean flags. Hence, even assigning a value of 1 to a macro is stretching it for me. (For example, what should it mean if you have #define _cplusplus 2? Should that be different in any way than 1?)

2) This last bit about them being "flags" goes along with the fact that I mostly use these for things I specify on the command line (or in the IDE) as conditional compilation flags. Indeed, on my software team, when we're writing C++, we're basically "prohibited" from using macros for anything else. And even in the conditional compilation case, we try to avoid them if we can solve the problem some other way (such as via modularity).

Both of these reasons relate to that same underlying assumption that macro use is to be avoided as much as possible (in C++) and so should not need the complexities of types or opaque semantics. If you don't make this assumption (and it's less common when programming in C, I know), then that changes things such that I imagine your points about #if might hold more sway.