易采站长站为您分析C/C++预处理器的一些工作,有助于理解编译器底层的工作流程,需要的朋友可以参考下
多么令人愉快的一个问题啊
就在被带到编译器那里之前,预处理器都会对你的源代码瞧上一瞧, 做一些格式化的工作,并执行任何你在源代码里面留给它来执行的指令.
像什么?
好吧,预处理器的指令就被叫做预处理器指令,而他们都以一个#开头.
像 #include 这样?
正确.
每一个被预处理器遇到的 # 命令都会导致在某种方式上对源代码的修改. 让我们来简单的研究研究它们,然后我们就会之后这背后都是怎么运转的了.
#include
包含其他库、类、接口等的头文件。预处理器实际上就只是把整个头文件复制到你的源代码里面 (是的,这就是包含防御之所以是件好事的原因了).
#define
谁会不喜欢宏呢! 预处理器会把所有定义的实体替换成被定义的代码. 定义会一直持续直到发现这个定义的 #undef 指令.
#ifdef
条件行为告诉预处理器包含在遇到声明的条件成立的条件块中的代码. 你可以就像if-else语句一样使用它们,从这里面选择: #ifdef, #ifndef, #if, #else, 以及 #elif, 而你总是要使用一个 #endif 作为结束。
#error #warning
用来向用户发送消息。预处理器会在 #error 处, 而不会在 #warning 处停下来. 两种情况下他都会发送他在指令背后(的括号里面)发现的字符串, 发送到屏幕作为输出,因此它是一种确保针对你的平台一切OK的手动方式.
#line
用来在你遇到编译错误时修改显示的错误行号和文件名. 例如,加入你需要查看一个来自编译的中间文件的源文件(可能是自动生成的).
#pragma
其它由编译器解释的特殊指令。你的编译器文档会告诉你指令是怎么用的,而你不要假定他们在全世界都通用哦.
#assert #unassert
这些在老程序里面总是特别受欢迎的 (好吧,只要我也曾经为这样一个程序工作过), 但是它们在现在已经过时了。强烈建议不使用它们,这意味着不要把他们放到新的代码里面
预定义宏
有许多可以利用的预定义宏:
__FILE__ 给出一个字符串的文件名
__LINE__ 给出当前的行号(整型)
__DATE__ 当前编译日期的字符串
__TIME__ 当前编译时间的字符串
__STDC__ 同编译器相关的,但常常被定义成1,以声明同ISO C标准兼容.
__cplusplus 在编译一个C++程序是总是会被定义
特别是开头两个在调试时真的非常有用。只要拿出它们俩,不用你自己编写文件和行处理类,就能神奇的让你获得丰富的信息输出.
你的编译器可能还支持其它的宏,例如,你这从 这里 获得(面向GCC)的整个宏清单.










