预编译阶段:
1、预编译阶段有哪些动作?
预编译阶段主要完成:在对code进行重塑,把源码塑造成另一种形式。有可能是替换,例如define,有可能是开关,控制某个头文件或者某段代码是否显示。
例如,#ifdef、endif用来控制一段的开启或者跨平台的服务,用#if 0 #endif调试一段code的情况。#define、typedef用来直接替换某个数据类型、某个类似函数。#include用于某个头文件包含,值得一提的是,可以把大型常量数组存储在inc文件中,再include该文件。
另外,这是只存在c/c++这种语言的一个步骤,java/python不存在这步骤。
2、预编译阶段可以有哪些替代?又有哪些不可替代的作用?
可替代:函数可以用内联函数替代;常量用const替代(注意define的定义等于全局定义);
不可替代:跨平台移植时的条件编译作用不可替代;
3、预编译阶段的缺点?
1、用多了会很乱,影响程序可读性;
2、预编译所使用的宏,其定义的函数不会进行类型检查。
编译阶段:
1、编译阶段有哪些动作?
编译阶段是将source code(人能看懂)翻译成机器能读懂的可执行文件(二进制code)。一般包括:词法分析、语法分析、语义检查和中间代码生成、代码优化。
2、编译阶段的常用指令?
[[deprecated()]]用于提醒编译器,接下来的为废弃接口,编译器会在调用该接口时报警告;
constructor:提醒编译器,该函数在main之前执行
destructor:提醒编译器,该函数在main结束后执行
unused:提醒编译器,现在没用但以后可能会用
hot:提醒编译器,多多优化这个函数
always_inline:强制这个函数作为内联函数
此外,还有static_assert,像断言一样,但它只在编译时起作用,运行时不起作用。这样,一旦断言内表达式为0,会直接编译错误,而非在运行师abort,程序崩溃。
3、预处理可以自定义宏,但编译不可以自定义属性标签,why?
因为预处理的宏,一般只涉及替换;而自定义的属性标签,是和编译器约定好,编译器按标签信息进行处理。所以编译不能自定义标签,否则编译器不知道如何处理。