I have never worked with #if, #ifdef, #ifndef, #else, #elif and #endif
The use of the preprocessor directives in this case is not entirely useful. But the use of these preprocessor directives is useful in many other cases.
These preprocessor directives can be used for conditional compilation. e.g. If some program has to be developed for multiple platforms then platform-specific constants can be given values. Changing these values compilation specific to the platform can be done while the whole code can be maintained as one big entity.
These are also useful while debugging. Test units can be compiled into the code and ran by using these conditional compilations while debugging and they can be stopped from compiling using these.
The example you showed doesn't seem helpful due to lack of other information. But here's an example that #if
is useful.
#if OS == LINUX
//do something
#elif OS == SOLARIS
//do something else
#else
//
#endif
The key is that #if
is evaluated in compile time, but if
is evaluated when program runs.
#if BYTE_ORDER == LITTLE_ENDIAN
//do something
#else
//do something else
#endif
Conditional preprocessor doesn't work like in your first example.
It's working with constants, you see? At compile time, it looks at the various conditions and puts in/omits source code according to it.
For example:
#define HAS_COMPARISON
int main() {
#ifdef HAS_COMPARISON
int i = 0;
if(i == 0) std::cout << "This";
else
#else
std::cout << "That";
#endif
}
With the define
set, it will set the variable i
and perform the comparison...in short, it will output This
. If you comment that define, the entire block will not be in your program which means that it will always output That
, without ever setting the variable or doing the comparison.
That's the most common use of preprocessor defines. You can also define values and compare those to have variable behaviour with the same define, but that's another issue.
Once more: Conditional preprocessor is evaluated at compile time, variable conditions are evaluated at runtime.
Conditional compilation means ifdef-ed out code is never actually in the final linked application. Just using language conditionals means both branches are in the final code making it bigger and potentially harder to test etc.
Use #ifdef
etc when you know at compile time what is required. Language conditionals are used when you don't know what you need until runtime.
benefits of preprocessor is that the code gets thrown out. It doesn't get compiled (which takes time) and it doesn't generate machine code which will be loaded into ram. If the decision is in a VERY tight loop run LOTS of times, there could be a speed improvement. Don't assume this is important unless you actually time it, though.
The detriments of preprocessor is that you obviously have to know the answer at compile time. The source code now contains a lot of code that may not ever be executed. It becomes harder to trace for a human because it's often difficult to determine what those compile-time values would have been.