Why use preprocessor #if statements instead of if() else?
Asked Answered
G

4

12

I see this being done all the time for example in the Linux kernel. What is the purpose of using the preprocessor commands vs. just normal C++ if else block? Is there a speed advantage or something?

Gardiner answered 6/4, 2014 at 18:13 Comment(0)
S
39

A preprocessor changes the C/C++ code before it gets compiled (hence pre processor).

Preprocessor ifs are evaluated at compile-time.

C/C++ ifs are evaluated at run-time.


You can do things that can't be done at run-time.

Adjust code for different platforms or different compilers:

#ifdef __unix__ /* __unix__ is usually defined by compilers targeting Unix systems */
#include <unistd.h>
#elif defined _WIN32 /* _Win32 is usually defined by compilers targeting 32 or 64 bit Windows systems */
#include <windows.h>
#endif

Ensure header file definitions are included only once (equivalent of #pragma once, but more portable):

#ifndef EXAMPLE_H
#define EXAMPLE_H

class Example { ... };

#endif

You can make things faster than at run-time.

void some_debug_function() {
#ifdef DEBUG
    printf("Debug!\n");
#endif
}

Now, when compiling with DEBUG not defined (likely a command line parameter to your compiler), any calls to some_debug_function can be optimized away by the compiler.

Sculptress answered 6/4, 2014 at 18:16 Comment(5)
Although the conditional include syntax is supported by pretty much any compiler, much cleaner way also supported by the majority of available compilers is to use "#pragma once" and not clutter global preprocessor name space.Cesena
if(DEBUG) printf("foo\n"); will also be optimized away to nothing (assuming printf is visible) with #define DEBUG 0 so you might want to tweak that part.Troublous
@Yakk: Most compilers will optimize out if (constantFalseCondition) doSomething(), or even a call to a compiler-visible function which can be determined to never do anything. On the other hand, if conditional "debug" statements need to use a global buffer which isn't used for anything else, an #ifdef can refrain from allocating the buffer when it isn't needed; conditional-execution statements cannot.Wendel
@Supercat agreed: which is why the point is valid, but the example is poor.Troublous
@Yakk: I've read many people commenting that languages shouldn't have things like #if because compilers can detect and eliminate dead code. A major problem with such thinking is that most linkers cannot eliminate dead global variables, and I don't think any can eliminate 99.9%-dead variables (which are used only by code that puts values there in anticipation of their being needed).Wendel
C
10

The preprocessor is run before the compilation pass, so the compiler won't even see anything that was in the not-taken #if branch.

#if DEBUG
int a;
#else
double b;
#endif

Compile:

gcc -c -DDEBUG=1 file.c

will see only "int a"

gcc -c file.c 

will see only "double b"

Cesena answered 6/4, 2014 at 18:17 Comment(0)
K
5

The preprocessor allows you to actually cut out or paste in to your source file, code to be compiled.

If it’s cut out, it’s gone. It’s like a comment, does nothing, is not compiled, and doesn't produce any code in the binary.

Developers will often use this technique to add code only in a debug build for debugging purposes or for adding or excluding code for specific operating systems.

Kaden answered 6/4, 2014 at 18:33 Comment(0)
S
-1

Let's discuss with an example below

#include <iostream>
using namespace std;

int main() {
    #if 1
        cerr<<"Preprocessor directives used";
    #endif
    if(0){
        int a=10;
    }
    return 0;
}
#if 0
int 10 = a;
int a = "hello";
#endif
  • if you run above code you don't get errors, but if you replace #if 0(outside main function code) content in normal if(0) we get syntax errors.
  • from this we can understand that preprocessors are executed at compile time and if first line is wrong inside block won't execute.
Spherule answered 24/4 at 9:51 Comment(1)
This doesn't answer the question. You've only described how preprocessor directives are different from normal code but not why to use them.Certainly

© 2022 - 2024 — McMap. All rights reserved.