Conditional compilation of C language # If, #elif, #else, #endif, #ifdef, #ifndef

Source: Internet
Author: User

Some programs in debugging, compatibility, platform porting and so on may want to create a different software by simply setting some parameters, this can of course, through the variable settings, all the code can be used to write in the initialization of the configuration, but in different cases may only use a portion of the code, There is no need to write all the code in, you can use conditional compilation, pre-compilation instructions to set the compilation conditions, different needs to compile different code.

(i) Conditional compilation method

Conditional compilation is achieved through precompiled directives, the main methods are:

1, #if, #elif, #else, #endif

 #if 条件 1
 代码段 1
#elif 条件 2
   代码段 2
...
#elif 条件 n
 代码段 n
#else
 代码段 n+1
#endif

That is, you can set different conditions for compiling different code at compile time, the expression in the precompiled instruction and the expression of the C language itself, such as logical operation, arithmetic operation, bit operation, etc. can be used in the precompiled instruction. Conditional compilation is possible because precompiled directives are processed before compilation, macro substitution by precompilation, conditional selection of code snippets, and final compilation of the code to be compiled.

#if的一般含义是, if the constant expression after # if is true, compile the code that it controls, such as when condition 1 is set up in code Snippet 1, Condition 1 does not set up again to see if the condition 2 is set up, if the condition 2 is set up the code segment 2, otherwise, and so on to judge other conditions, The final code snippet N+1 is compiled if the condition 1-n is not force-coded.

2, #ifdef, #else, #endif或 #ifndef, #else, #endif

Another way to conditionally compile is to use the #ifdef and #ifndef commands, which represent "if there is a definition" and "if there is no definition" respectively. There is a definition of whether a macro is defined by a #define directive when compiling this piece of code, #ifndef指令指找不到通过 a macro defined by a # define, which can be defined in the closing face of this instruction in the current file, or in another file, but included in the file before this instruction.

#ifdef的一般形式是:

 #ifdef macro_name
    代码段 1
#else
    代码段 2
#endif


#ifdef的一般形式是:

#ifndef macro_name
    代码段 2
#else
    代码段 1
#endif

The effect of these two pieces of code is exactly the same.

3, through the macro function defined (macro_name)

The parameter is a macro name (no need to add ""), if the macro_name is defined and returns True, otherwise false, the function can write more complex conditional compilation instructions such as

 #if defined(macro1) || (!defined(macro2) && defined(macro3))
...
#else
...
#endif

(ii) Conditional compilation techniques and examples

(1) #ifdef和 #defined () comparison

First of all, compare the two methods, the first method can only judge a macro, if the conditions are more complex to achieve a more annoying lock, the latter is more convenient. If there are two macros macro_1,macro_2 only two macros are defined before the code snippet A is compiled, respectively, the following are implemented:

 #ifdef MACRO_1
#ifdef MACRO_2
    代码段 A
#endif
#endif

或者
#if defined(MACRO_1) && defined(MACRO_2)
#endif

Similarly, to implement more complex conditions with #ifdef is more cumbersome, so it is recommended to use the latter, because even if the current code with a simple conditional compilation, later in the maintenance, upgrade may increase, with the latter maintainability is stronger. The old compiler may not implement the #defined () directive, and C99 has been added to the standard. To be compatible with older compilers, #ifdef instructions are also required.

2. #if与 #ifdef或 # if defined () comparison

For example, I wrote a PRINTF function, want to use a macro my_printf_en to achieve conditional compilation, with # if can be implemented as follows

Conditional compilation of C language

 #define MY_PRINTF_EN 1

#if MYS_PRINTF_EN == 1
 int printf(char* fmt, char* args, ...)
{
    ...
}
#endif

If the macro my_printf_en is defined as 1, the code is compiled, and if the macro definition is not 1 or the macro is not defined, the code is not compiled. This can also be achieved through #ifdef or #defined (), such as

 #define MY_PRINTF_EN 1

#if defined(MY_PRINTF_EN)
 int printf(char* fmt, char* args, ...)
{
    ...
}
#endif

In this case, the two approaches are similar, but imagine if you write two printf functions in order to save code, use different printf functions under different circumstances, one is a full-featured standard version of the Lite version, such as:

 #define MY_PRINTF_SIMPLE

#ifdef MY_PRINTF_SIMPLE
   void printf(*str) // 向终端简单地输出一个字符串
{...
}
#endif
#ifdef MY_PRINTF_STANDARD
 int printf(char* fmt, char* args, ...)
{...
}
#endif

同样可以用#if defined()实现
#define MY_PRINTF_SIMPLE

#if defined(MY_PRINTF_SIMPLE)
   void printf(*str) // 向终端简单地输出一个字符串
{
    ...
}
#elif defined(MY_PRINTF_STANDARD)
 int printf(char* fmt, char* args, ...)
{
    ...
}
#endif

Both methods can be implemented, but the latter is more convenient. But imagine if you have three versions, the former is more troublesome, but the method is similar, with the latter is more convenient, but still need three macro control, you have to live three macros, improve the use of # # can be used with a macro direct control of n cases such as:

 #define MY_PRINTF_VERSION     1

#if MY_PRINTF_VERSION == 1
   void printf(*str) // 向终端简单地输出一个字符串
{
    ...
}
#elif MY_PRINTF_VERSION == 2
 int printf(char* fmt, char* args, ...)
{
    ...
}
#elif MY_PRINTF_VERSION == 3
int printf(unsigned char com_number, char* str)
{
    ...
}
#else
    默认版本
#endif

That way, you just have to change the numbers to make the version choices.

It seems to be better to use # If, imagine the following: You write a configuration file called Config.h to configure some macros, through these macros to control the code, such as your CONFIG.H macro

#define MY_PRINTF_EN 1

To control whether you need to compile your own printf function, and in your source code file PRINTF.C The following instructions

 #i nclude "config.h"
#if MY_PRINTF_EN == 1
 int printf(char* fmt, char* args, ...)
{
    ...
}
#endif

But there is also a problem, that is, if you forget to add macro my_printf_en to Config.h, the PRINTF function that you write will not be compiled, and some compilers will warn you that my_printf_en is undefined. If you have two versions that you want to have a default version, you can do so in PRINTF.C

 #incldue "config.h"
#if !defined(MY_PRINTF_VERSION)
  #define MY_PRINTF_VERSION   1
#endif

#if MY_PRINTF_VERSION == 1
   void printf(*str) // 向终端简单地输出一个字符串
{
    ...
}
#elif MY_PRINTF_VERSION == 2
 int printf(char* fmt, char* args, ...)
{
    ...
}
#elif MY_PRINTF_VERSION == 3
int printf(unsigned char com_number, char* str)
{
    ...
}
#endif

 这种情况下还得用到#ifdef或#if defined(),你可以不用动主体的任何代码,只需要修改printf.c文件中MY_RPINTF_VERSION宏的数字就可以改变了,如果用前面那种方法还得拖动代码,在拖动中就有可能造成错误。

Imagine, if the software upgrade, or have a big change, there are three versions, now only two versions, such as

 #if MY_PRINTF_VERSION == 2
 int printf(char* fmt, char* args, ...)
{
    ...
}
#elif MY_PRINTF_VERSION == 3
int printf(unsigned char com_number, char* str)
{
    ...
}
#endif

Because these core code does not want to let people who use this code care, they only need to modify the Config.h file, it is necessary to achieve compatibility in the PRINTF.C. If someone previously configured macro my_printf_version in Config.h to be 1, there

#define My_printf_version 1

And now there is no 1 version, what to do to be compatible? That can, of course, be implemented with more complex conditions such as:

 #if MY_PRINTF_VERSION == 2 || MY_PRINTF_VERSION == 1
 int printf(char* fmt, char* args, ...)
{
    ...
}
#elif MY_PRINTF_VERSION == 3
int printf(unsigned char com_number, char* str)
{
    ...
}
#endif

However, there is another way to use the #undef command

 #if MY_PRINTF_VERSION == 1
  #undef MY_PRINTF_VERSION
  #define MY_PRINTF_VERSION  2
#endif
#if MY_PRINTF_VERSION == 2
 int printf(char* fmt, char* args, ...)
{
    ...
}
#elif MY_PRINTF_VERSION == 3
int printf(unsigned char com_number, char* str)
{
    ...
}
#endif

If you put the name of the macro wrong, and you define the my_printf_en as the my_print_en, then you can not compile the code with #ifdef my_printf_en or # if defined (my_printf_en) control. Check up and difficult to check, with # if My_printf_en ==1 control is very good to check, because you have my_printf_en defined as my_print_en, then my_printf_en is not actually defined, then the compiler will give a warning # if my_printf_ EN = = 1 My_printf_en is not defined, but the error is relatively fast.

(GO) conditional compilation of C language # If, #elif, #else, #endif, #ifdef, #ifndef

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.