Summary
1)条件编译的行为类似于
C语言中的if else
;
条件编译是预编译指示命令
,用于控制是否编译某段代码
;
2)预编译器
根据条件编译指令有选择的删除代码
,所以编译器不知道
代码分支的存在
3)if else在运行期
进行分支判断,一定会被编进目标代码
;条件编译指令
在预编译期
进行分支判断,可能产生不同的代码段,因此编进目标代码的代码段不确定
4)可以通过命令行定义宏
:gcc -Dmacro=val file.c
或gcc -Dmacro file.c
5)#include
本质
是将已经存在的文件内容插入
到当前文件中;#include
的间接包含同样会产生嵌入文件内容操作。条件编译指令#ifndef _FILE_H_ #define _FILE_H #endif
可以解决这种头文件重复包含
的错误。
6)条件编译指令只是可以在同一个.c文件中,防止重复包含
;如果头文件中有了符号的定义
,但是在一个工程的不同c文件里都进行了include
,这时候编译这两个文件也会有重复定义
的错误(因为两份include在各自的c文件里都定义了一个global,在同一个全局作用域里定义了同名的symbol)。所以,头文件中只声明、不定义
!
7)工程中的条件编译主要用于:不同的产品线共用一份代码
;区分编译产品的调试版和发布版
条件编译分析
条件编译的行为类似
于C语言中的if...else...
;
条件编译是预编译指示命令
,用于控制是否编译
某段代码;
1、条件编译于if...else的区别
预编译器
根据条件编译指令有选择的删除代码
,所以编译器不知道
代码分支的存在if...else
语句在运行期
进行分支判断;条件编译指令
在预编译期
进行分支判断- 可以通过
命令行定义宏
:gcc -Dmacro=val file.c
或者gcc -Dmacro file.c
#define C1int main()
{
#if (C==1)
printf("if true\n");
#else
printf("if false\n");
#endifreturn 0;
}
gcc -E test.c -o test.i
// 单步编译后得到的中间文件
# 1 "test.c"
# 1 ""
# 1 ""
# 1 "test.c"int main()
{
printf("if true\n");
return 0;
}
分析:
- 经过预编译期的处理后,得到的中间文件中#if #else #endif都被删掉了,这也说明了上面的
预编译器根据条件编译指令有选择的删除代码
,所以编译器在拿到中间.i文件后,根本就不知道这些代码分支的存在。 - 也说明,
#if #else #endif是在预编译期进行判断
的,而if else是在运行期才会判断
// 上述代码中去掉#define C 1 // 使用命令来定义宏 gcc -DC=1 test.c 编译后的运行结果为:if truegcc -DC test.c gcc -DC test.c 编译后的运行结果为:if true
#ifdef #else #endif
进行预编译分支判断:#ifdef C printf("yes, defined"); #else printf("no, undefined"); #endif以上代码进行编译: gcc -DC test.c 输出:yes, definedgcc test.c 输出:no, undefined
#include
本质
是将已经存在的文件内容插入
到当前文件中#include
的间接包含同样会产生嵌入文件内容操作。
文章图片
对以上代码进行单步编译
gcc -E test.c -o test.i
gcc -S test.i -o test.s
分析:单步编译后,在中间.i文件中,global的定义出现了2次,后续的编译过程自然会出现重定义的错误。
文章图片
重复包含的解决方式:
在头文件test.h和global.h中加上条件编译指令
。#ifndef _HEADER_FILE_H_
#define _HEADER_FILE_H_
// SRC
#endif
注意:
条件编译指令只是可以在同一个.c文件中,防止重复包含
;如果头文件中有了符号的定义
,但是在一个工程的不同c文件里都进行了include
,这时候编译这两个文件也会有重复定义
的错误(因为两份include在各自的c文件里都定义了一个global,在同一个全局作用域里定义了同名的symbol)。所以,头文件中只声明、不定义
!示例代码:
依旧是上面的test.c test.h global.h,再加一个test2.c文件,其中#include "test.h"
执行:gcc test.c test2.c
输出:multiple definition of 'global'
3、条件编译工程中的应用
if else
被编译器
处理,必然被编译进目标代码
;#if #else #endif
被预编译器
处理,可以按不同的条件编译不同的代码段,因而会产生不同的目标代码
- 工程中的条件编译主要用于:
不同的产品线共用一份代码
;区分编译产品的调试版和发布版
文章图片
如有错漏之处,恳请指正。
推荐阅读
- c/c++|有感 Visual Studio 2015 RTM 简介 - 八年后回归 Dot Net,终于迎来了 Mvc 时代,盼走了 Web 窗体时代...
- C/C++|C/C++ basis 02
- Qt实战|Qt+OpenCV联合开发(二十一)--图像翻转与旋转
- Qt实战|Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取
- Qt实战|Qt+OpenCV联合开发(十三)--通道分离与合并
- opencv|Qt+OpenCV联合开发(十六)--图像几何形状绘制
- Qt实战|Qt+OpenCV联合开发(十七)--随机数与随机颜色
- SNAT的MASQUERADE地址选择与端口选择
- IPTABLES的连接跟踪与NAT分析
- IPVS分析