C language #if, #ifdef, #ifndef conditional compilation usage summary

Conditional compilation is a means of statically compiling code based on the actual definition of macros (certain types of conditions). Compilation conditions can be determined based on the value of an expression or whether a particular macro is defined.

The most common conditional compilation is to prevent repeated inclusion of macros in header files. Almost all header files must be edited in the following way to prevent repeated inclusion . The form is similar to the following code:

#ifndef ABCD_H
#define ABCD_H

// ... some declaration codes

#endif // #ifndef ABCD_H

In C files, there are usually definitions similar to the following:

#ifdef _DEBUG

// ... do some operations

#endif

#ifdef _WIN32

// ... use  Win32 API

#endif

Common Conditional Compilation Directives

1. #if: If the condition is true, perform the corresponding operation.
2. #elif: Similar to the usage of elseif, when the previous condition is false, then judge whether the condition is true, and if it is true, perform the corresponding operation.
3. #else: If all the previous conditions are false, perform the corresponding operation.
4. #ifdef: If the macro has been defined, perform the corresponding operation.
5. #ifndef: If the macro is not defined, perform the corresponding operation.
6. #endif : End the corresponding conditional compilation instruction. (cannot be omitted)
defined : used in conjunction with #if, #elif to determine whether a macro is defined

#if,#elif,#else与#endif

The #if directive is much like the if statement in C. #if is followed by a constant expression, if the expression is non-zero, the expression is true, and all C codes between #if and #endif are executed; if the expression is 0, the expression is false, and the code in the middle does not participate compile.

#if can be used with constant expressions. Common formats are as follows:

#if 常量表达式1
// ... some codes
#elif 常量表达式2
// ... other codes
#elif 常量表达式3
// ...
...
#else
// ... statement
#endif

The above #if, #elif, #else can be understood in connection with the if elseif else of the conditional judgment statement. Similarly, #elif, #else do not necessarily need to exist.
A constant expression can be a legal C constant expression including macros, arithmetic operations, logical operations, etc. If the constant expression is an undefined macro, its value is treated as 0.

#if MACRO_NON_DEFINED // 等价于

#if 0

When judging whether a macro is defined, #if should be avoided, because the value of the macro may be defined as 0. Instead, use #ifdef or #ifndef.

Here are a few examples:
Example 1:

#if 0
//代码1
#endif

The above usage is equivalent to the code between #if 0 and #endif being commented out, and it will generally be grayed out in the IDE environment. If you need this code to participate in compilation, just change #if 0 to #if 1. But this kind of usage is best used only temporarily during the debugging stage, and it does not have much practical significance, because it is /* */similar to the comment symbol.

Example 2:

#define FUNCTION 0

#if FUNCTION
//代码1
#endif

The above usage is relatively common, that is, the FUNCTION macro is defined as 0 or 1, which determines whether the code between #if FUNCTION and #endif participates in compilation.
The macro definition of FUNCTION can be placed in a header file for configuration, which is convenient for centralized control.

Example 3:

#define FUNCTION 0

#if FUNCTION
//代码1
#else
//代码2
#endif

Similar to Example 2, if the FUNCTION macro is defined as 0 or 1, if FUNCTION is 1, code 1 between #if FUNCTION and #else will participate in compilation, if FUNCTION is 0, then code 2 between #else and #endif will participate in compilation.

Example 4:

#define FUNCTION 0

#if (FUNCTION == 0)
//代码1
#elif (FUNCTION == 1)
//代码2
#elif (FUNCTION == 2)
//代码3
#endif

The FUNCTION macro is defined as 0 or 1 or 2. If FUNCTION is 0, code 1 will participate in compilation; if FUNCTION is 1, code 2 will participate in compilation; if FUNCTION is 2, code 3 will participate in compilation.
Since 0, 1, 2 cannot be understood intuitively, we can also define a layer of macros for 0, 1, 2 to increase the readability of the code, such as:

#define FUN_A 0
#define FUN_B 1
#define FUN_C 2

#define FUNCTION FUN_A

#if (FUNCTION == FUN_A)
//代码1
#elif (FUNCTION == FUN_B)
//代码2
#elif (FUNCTION == FUN_C)
//代码3
#endif

Example 5:

#define FUN_A 1
#define FUN_B 1

#if (FUN_A && FUN_B)
//代码1
#endif

Only when FUN_A and FUN_B are defined as 1 at the same time, code 1 will participate in compilation, otherwise code 1 will not participate in compilation.

Example 6:

#define FUNCTION 1

#if (FUNCTION < 5)
//代码1
#endif

Code 1 participates in compilation only when the definition of FUNCTION is less than 5, otherwise Code 1 does not participate in compilation.

#ifdef, #ifndef, #else and #endif

Precompiled directives that are relatively commonly used in conditional compilation. The schema is as follows:

#ifdef ABC
// ... codes while definded ABC
#elif (CODE_VERSION > 2)
// ... codes while CODE_VERSION > 2
#else
// ... remained cases
#endif // #ifdef ABC

#ifdef is used to judge whether a macro is defined, which is just the opposite of the function of #ifndef. The two only support judging whether a single macro has been defined. In the above example, the two can be interchanged.
If multi-conditional precompilation is not required, both #elif and #else in the above example can be omitted.

Since #ifdef can only determine whether a single macro is defined, there are naturally not as many tricks that can determine an expression after #if, so a large number of examples cannot be given.

#if defined

defined is used to test whether a macro is defined. defined(name): Returns 1 if the macro is defined, otherwise returns 0.
It is used in conjunction with #if, #elif, and #else to determine whether the macro is defined. At first glance, it seems redundant, because there are already #ifdef and #ifndef. defined can be used to declare multiple judgment conditions in a judgment statement ; #ifdef and #ifndef only support judging whether a macro is defined or not.

similar:

#if defined(VAX) && defined(UNIX) && !defined(DEBUG) 

Of course, if it is to judge a single condition, there is no difference between #if defined and #ifdef.

#if defined(VAX)
#ifdef VAX

#if !defined

#if !defined is similar to #ifndef and is used to judge that the macro is not defined.
The difference is that #if !defined can judge multiple (similar to the previous #if defined).

#if !defined(VAX)
#ifndef VAX

Both have the same effect.

The essence of #if !defined is still #if defined, so they can be combined

#if defined(VAX) && defined(UNIX) && !defined(DEBUG) 

This example is when both VAX and UNIX are defined, and DEBUG is not defined, then the condition is true.

Guess you like

Origin blog.csdn.net/weixin_44788542/article/details/130922902