1

Summary

1) the behavior of conditional compilation similar to the C language if else ; conditional compilation is precompiled instruction command, for controlling whether a certain code is compiled;

2) pre-compiler delete code according to conditional compilation instructions, so the compiler does not know the existence of the code branch

3) If else branch judgment is performed during the runtime of , it will be compiled into the target code ; conditional compilation instruction branch judgment during the precompilation period of may produce different code segments, so the code segment compiled into the target code is not Sure

4) command line: gcc -Dmacro=val file.c or gcc -Dmacro file.c

5) #include essentially inserts the existing file content into the current file; #include will also generate embedded file content operations. Conditional compilation instruction #ifndef _FILE_H_ #define _FILE_H #endif can solve this kind of error of repeated inclusion

6) The conditional compilation instruction can only be included in the same .c file to prevent repeated inclusion; if there are symbol definitions in the header file, but in the different c files of a project, include is carried out, then compile this Two files will also have repeated definition (because the two include defines a global in their respective c files, and defines the symbol with the same name in the same global scope). Therefore, the header file is only declared but not defined!

7) Conditional compilation in the project is mainly used for: different product lines share a code; distinguishes the debug version and the release version of the compiled product

Conditional compilation analysis

Conditional compilation behavior similar to the C language if...else... ;
Conditional compilation is the precompilation instruction command, which is used to control whether 161c5e07acd824 compiles a code;

1. The difference between conditional compilation and if...else

  • pre-compiler delete the code according to the conditional compilation instruction, so the compiler does not know the existence of the code branch
  • if...else statement performs branch judgment during the runtime conditional compilation instruction performs branch judgment during the precompilation period
  • The macro can be command line: gcc -Dmacro=val file.c or gcc -Dmacro file.c
#define C1

int main()
{
    #if (C==1)
        printf("if true\n");
    #else
        printf("if false\n");
    #endif    

    return 0;
}
gcc -E test.c -o test.i
// 单步编译后得到的中间文件
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"

int main()
{
        printf("if true\n");
    return 0;
}

analyze:

  • After processing in the pre-compilation period, #if #else #endif in the obtained intermediate file is deleted, which also shows that the above pre-compiler selectively deletes the code according to the conditional compilation instruction, so the compiler is taking After reaching the intermediate .i file, there is no idea of the existence of these code branches.
  • It also shows that #if #else #endif is judged during the pre-compilation period, and if else is judged during the runtime
  • // 上述代码中去掉#define C 1
    // 使用命令来定义宏
    gcc -DC=1 test.c
    编译后的运行结果为:if true
    
    gcc -DC test.c
    gcc -DC test.c
    编译后的运行结果为:if true

Use #ifdef #else #endif for pre-compilation branch judgment:

  • #ifdef C
      printf("yes, defined");
    #else
      printf("no, undefined");
    #endif
    
    以上代码进行编译:
    gcc -DC test.c
    输出:yes, defined
    
    gcc test.c
    输出:no, undefined

2. Conditional compilation solves the compilation errors repeatedly contained in the header file

  • #include essentially inserts the existing file content into the current file
  • #include will also produce embedded file content operations.
对以上代码进行单步编译
gcc -E test.c -o test.i
gcc -S test.i -o test.s

Analysis: After single-step compilation, the definition of global appears twice in the intermediate .i file, and redefinition errors will naturally occur in the subsequent compilation process.
image.png

Solution for repeated inclusion: adds conditional compilation instructions to the header files test.h and global.h.

#ifndef _HEADER_FILE_H_
#define _HEADER_FILE_H_
// SRC
#endif

Note that : conditional compilation instructions can only be included in the same .c file to prevent repeated inclusion; if there are symbol definitions in the header file, but the a project is included in different c files, at this time Compiling these two files will also have repeated definition (because the two include defines a global in their respective c files, and defines the symbol with the same name in the same global scope). Therefore, the header file is only declared but not defined!
Sample code:

依旧是上面的test.c test.h global.h,再加一个test2.c文件,其中#include "test.h"
执行:gcc test.c test2.c
输出:multiple definition of 'global'

3. Application in Conditional Compilation Project

  • if else is processed by the compiler, must be compiled into the target code; #if #else #endif is processed by the pre-compiler, which can compile different code segments according to different conditions, so will generate different target codes
  • Conditional compilation in the project is mainly used for: different product lines share a code; distinguishes the debug version and release version of the compiled product

This article is summarized from "C Language Advanced Course" by Tang Zuolin from "Ditai Software Academy".
If there are any errors or omissions, please correct me.


bryson
169 声望12 粉丝