How #if, #elif and #else Directives work in C

«
»
This C Tutorial explains how #if, #elif and #else Directives works.

We are familiar with

    if (conditional exp.) {
        /* statements */
    }
    else if (conditional exp.) {
        /* other statements */
    }
    else {
        /* other statements */
    }

construct which branches program execution depending on condition evaluation. But these construct affect program execution at run time. #if, #elif and #else are preprocessor directives which work alike if, else if and else construct
but during pre-compilation of the program. They are used to make the compiler see what fragment of code to be compiled or skipped. Therefore, these constructs form conditional compilation. Consider their syntax for use in program,

advertisement
#if(constant-exp)
    /* other statements */
#elif (constant-exp)
    /* other statements */
#else
    /* other statement */
#endif

Notice that “constant-exp” must be #define’d symbols or literal constants. Variables which don’t attain their values until runtime aren’t legal candidates because their values can’t be predicted during compile time. Let’s see a simple C program implementing them.

#include <stdio.h>
 
#define X 10
#define Y 0
#define Z 100
 
int main(void)
{
    int x = 10, y = 0, z = 100;
 
#if X
    printf("x is %d\n", X);
#elif Y
    printf("y is %d\n", Y);
#else
    printf("z is %d\n", Z);
#endif
 
    return 0;
}

preprocessor output, a file with .i extension, of the program follows,

advertisement
int main(void)
{
    int x = 10, y = 0, z = 100;
 
 
    printf("x is %d\n", 10);
 
 
 
 
 
 
    return 0;
}

Notice that printf() statement following

#if X

advertisement

where X was a symbolic constant with value 10

is put in the output while other #constructs simply deleted by the preprocessor.
The output of preprocessor is given to compiler which produces assembly code, file with .s extension.

For ex., debugging statements written in the program would not be required in the production version of the program. We would rather not remove them physically as those might again be required during maintenence modification of the program. For ex.,

#define DEBUG    printf("value of x = %d and y = %d\n", x, y)
 
int main(void)
{
    /* other statements */
 
    #if 0
     DEBUG;
    #endif
 
    return 0;
}

Notice in above program, constant expression following #if is zero ‘0’. Therefore, preprocessor simply deletes DEBUG statement enclosed within #if construct with its maching #endif. Nevertheless, these statements are physically present in the program.

advertisement

Sanfoundry Global Education & Learning Series – 1000 C Tutorials.

If you wish to look at all C Tutorials, go to C Tutorials.

Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!
advertisement
advertisement
advertisement
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He is Linux Kernel Developer & SAN Architect and is passionate about competency developments in these areas. He lives in Bangalore and delivers focused training sessions to IT professionals in Linux Kernel, Linux Debugging, Linux Device Drivers, Linux Networking, Linux Storage, Advanced C Programming, SAN Storage Technologies, SCSI Internals & Storage Protocols such as iSCSI & Fiber Channel. Stay connected with him @ LinkedIn