cc条件编译
‘壹’ vs中debug和release版本的区别
vs中的程序有debug和release两个版本。
1、版本不同
Debug通常称为调试版本,通过一系列编译选项的配合,编译的结果通常包含调试信息,而且不做任何优化,以为开发人员提供强大的应用程序调试能力。
而Release通常称为发布版本,是为用户使用的,一般客户不允许在发布版本上进行调试。
2、运行效果不同
debug程序通常比release程序要慢,尤其是处理视频方便release要比debug快很多。
3、算法不同
debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc, 而release的赋值近似于随机。
(1)cc条件编译扩展阅读:
二者的编译选项。
Debug 版本:
/Od 关闭优化开关
/D "_DEBUG" 相当于 #define _DEBUG,打开编译调试代码开关(主要针对assert函数)
/ZI 创建 Edit and continue(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译
/GZ 可以帮助捕获内存错误
/Gm 打开最小化重链接开关,减少链接时间
Release 版本:
/MD /ML 或 /MT 使用发布版本的运行时刻函数库
/O1 或 /O2 优化开关,使程序 最小或最快
/D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数)
/GF 合并重复的字符串,并将字符串常量放到只读内存,防止被修改
可以理解Debug 和 Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。
‘贰’ C语言编译原理
编译共分为四个阶段:预处理阶段、编译阶段、汇编阶段、链接阶段。
1、预处理阶段:
主要工作是将头文件插入到所写的代码中,生成扩展名为“.i”的文件替换原来的扩展名为“.c”的文件,但是原来的文件仍然保留,只是执行过程中的实际文件发生了改变。(这里所说的替换并不是指原来的文件被删除)
2、汇编阶段:
插入汇编语言程序,将代码翻译成汇编语言。编译器首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,编译器把代码翻译成汇编语言,同时将扩展名为“.i”的文件翻译成扩展名为“.s”的文件。
3、编译阶段:
将汇编语言翻译成机器语言指令,并将指令打包封存成可重定位目标程序的格式,将扩展名为“.s”的文件翻译成扩展名为“.o”的二进制文件。
4、链接阶段:
在示例代码中,改代码文件调用了标准库中printf函数。而printf函数的实际存储位置是一个单独编译的目标文件(编译的结果也是扩展名为“.o”的文件),所以此时主函数调用的时候,需要将该文件(即printf函数所在的编译文件)与hello world文件整合到一起,此时链接器就可以大显神通了,将两个文件合并后生成一个可执行目标文件。
‘叁’ 多个文件的条件编译,需要注意些什么
不能在同一个文件中包含头文件两次。一般不会犯这种错误,但是当使用包含了一个头文件的文件时有可能在不知情的情况下犯这个错误。
使用预处理器指令#ifndef来解决上面的问题。语名#ifndef hyong…..#endi表示仅当以前没有使用预处理器编译指令#define定义的名称hyong时才处理#ifndef….#endif之间的语句。#define通常创建符号常量,比如#define H 3;把常量3定义为名字H,但只使用#define就能创建名称,比如#define H;就创建了一个名称H。完整的#ifndef….#endif语句的例子如下:#ifndef HY #define HY void g(); #endif;该语句的执行顺序为:编译器首先遇到该头文件时,名称HY没有被定义,这时编译器就将查看#ifndef….#endif之间的内容,并读取到#define HY这一行。如果在同一文件中遇到包含该头文件的代码时,编译器就知道HY这个名字已经被#define定义了,从而跳过#ifndef….#endif之间的内容。注意这种方法并不能防止头文件被包含两次,而只是让他忽略除第一次包含之外的所有内容。
上面的内容节选自本人文库里的文章《C++名称空间与作用域专题》,希望对你有帮助,如果你对预处理器不了解,可以再去下载本人的另一篇文章《C++宏,预处理器,RTTI,typeid与强制类型转换专题》