Gcc 编译的背后--预处理
来源:互联网 发布:sql 字段累加 编辑:程序博客网 时间:2024/05/16 12:47
预处理
简述
预处理是 C 语言程序从源代码变成可执行程序的第一步,主要是 C 语言编译器对各种预处理命令进行处理,包括头文件的包含、宏定义的扩展、条件编译的选择等。
以前没怎么“深入”预处理,脑子对这些东西总是很模糊,只记得在编译的基本过程(词法分析、语法分析)之前还需要对源代码中的宏定义、文件包含、条件编译等命令进行处理。这三类的指令很常见,主要有 #define
,#include
和 #ifdef ... #endif
,要特别地注意它们的用法。
#define
除了可以独立使用以便灵活设置一些参数外,还常常和 #ifdef ... #endif
结合使用,以便灵活地控制代码块的编译与否,也可以用来避免同一个头文件的多次包含。关于 #include
貌似比较简单,通过 man
找到某个函数的头文件,复制进去,加上 <>
就好。这里虽然只关心一些技巧,不过预处理还是隐藏着很多潜在的陷阱(可参考《C Traps & Pitfalls》)也是需要注意的。下面仅介绍和预处理相关的几个简单内容。
打印出预处理之后的结果
$ gcc -E hello.c
这样就可以看到源代码中的各种预处理命令是如何被解释的,从而方便理解和查错。
实际上 gcc
在这里调用了 cpp
(虽然通过 gcc -v
仅看到 cc1
),cpp
即 The C Preprocessor,主要用来预处理宏定义、文件包含、条件编译等。下面介绍它的一个比较重要的选项 -D
。
在命令行定义宏
$ gcc -Dmacro hello.c
这个等同于在文件的开头定义宏,即 #define macro
,但是在命令行定义更灵活。例如,在源代码中有这些语句。
#ifdef DEBUGprintf("this code is for debugging\n");#endif
如果编译时加上 -DDEBUG
选项,那么编译器就会把 printf
所在的行编译进目标代码,从而方便地跟踪该位置的某些程序状态。这样 -DDEBUG
就可以当作一个调试开关,编译时加上它就可以用来打印调试信息,发布时则可以通过去掉该编译选项把调试信息去掉。
- Gcc 编译的背后--预处理
- GCC编译的背后( 预处理和编译 汇编和链接 )
- GCC编译的背后( 预处理和编译 汇编和链接)
- GCC编译的背后( 预处理和编译 汇编和链接 )
- GCC编译的背后( 预处理和编译 汇编和链接 )
- GCC编译的背后( 预处理和编译 汇编和链接 )
- gcc编译的背后(预处理、编译、汇编和链接) 一
- GCC编译的背后( 预处理和编译 汇编和链接 )
- GCC编译的背后( 预处理和编译 汇编和链接 )
- GCC编译的背后( 预处理和编译 汇编和链接 )
- GCC编译的背后( 预处理和编译 汇编和链接 )
- GCC编译的背后( 预处理和编译 汇编和链接 )
- GCC编译的背后( 预处理和编译 汇编和链接 )
- GCC编译的背后( 预处理和编译 汇编和链接 )
- GCC编译的背后
- gcc编译的背后
- Gcc 编译的背后
- GCC编译背后(第一部分:预处理和编译)
- React.js入门杂记
- automake编写完整的项目---静态库+可执行文件+rpm包
- 01 java语言编程的hello world
- [编程题] 工作安排
- POJ 2586 How far away ? 离线LCA
- Gcc 编译的背后--预处理
- 用jquery实现三级联动
- 88. Merge Sorted Array
- 基于Spring boot的Spring data jpa连接MySQL数据库
- Solr搜索引擎——中文分词器
- [编程题] 集合
- 常见邮件发送失败原因分析以及解决方法
- 中文分词算法概述
- [编程题] 奇怪的表达式求值