Skip to main content
Engineering LibreTexts

14.2: Conditional Compilation

  • Page ID
    35867
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    Suppose for a moment that you wish to create two or more versions of a program that differ only in mild ways. While it is possible to maintain multiple sets of source code for each, this can be a pain when it comes time to fix a bug or add a feature since alterations will need to be made to each of the source files. It would be much easier to somehow “flag” parts of the source code as belonging to different versions of the program and then have the compiler or preprocessor do the work for you. This is exactly what conditional compilation is. To do this, we exploit the power of the preprocessor. We have already looked at the #define directive as a way of defining constants or creating macros, but we can take it further. Look at the following example fragment:

    #define VERSION_A
    
    #ifdef VERSION_A
    char title[] = "This is version A";
    #else
    char title[] = "This is some other version”;
    #endif
    

    The #if/#else/#endif directives act similarly to the if/else commands. Note that parentheses are not used to block multi-line sections (hence the need for the #endif directive). In the example above, the char array title is initialized to "This is version A". If we commented out the #define VERSION A line, then title would be initialized to "This is some other version". In some IDEs it is possible to create variations on projects. Within each project you can define certain symbols (such as VERSION_A). This way you wouldn’t even have to comment/uncomment the #define, but just select the desired project variation. Note that it is possible to nest #if/else directives. Further, you are not limited to simply altering global declarations. This technique can be used on code as well as data. In fact, entire functions may be added or excluded in this way. Here is another typical use:

    void some func( void )
    {
        //...code stuff...
    
    #ifdef DEBUG
        printf("Error in some_func, x=%d\n", x );
    #endif
    
    //...rest of function...
    }
    

    If DEBUG is defined, the printf() call will be included in the executable. If it is not defined, it is as if the printf() call never existed.


    This page titled 14.2: Conditional Compilation is shared under a CC BY-NC-SA 4.0 license and was authored, remixed, and/or curated by James M. Fiore via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.

    • Was this article helpful?