1 常见术语
Term | 中文解释 |
---|---|
Declare | 声明 |
cv-qualification (const-and-volatile-qualification) | cv限定 |
Dangling | 悬挂 |
Universal Reference | 万能引用 |
Perfect Forwarding | 完美转发 |
Uniform Initialization | 统一初始化 (使用 {} 初始化) |
Aggregate | 聚合体 |
Delegate constructor | 委托构造函数 |
ADL (Argument-Dependent Lookup) | 参数依赖查找 |
RVO (Return Value Optimization) | 返回值优化 |
SFINAE (Substitution Failure Is Not An Error) | |
Linker | 链接器 |
Static Storage | 静态存储 |
Stack | 栈 |
Cv-qualification: const-and-volatile-qualification
用的比较多的就是const
限定符;
2 Namespace:命名空间
Namespace表示某些工具集合的作用域;
“作用域前面加::”:显式调用全局域关键字
关于“C++中‘作用域前面加::’做法的用处”,请参考知乎回答《C++中“作用域前面加::”:可以减少重名的可能性》
简单来说,其目的就是可以显式指定:准备调用的关键字符号是来自于全局空间global,这样编译器则会从全局空间开始检索该符号;
我们用一个简单的demo来验证这一点:
#include <iostream>
using namespace std;
int a = 3;
int main() {
int a = 1;
cout<<a<<endl;
cout<<::a;
}
>>>
1
3
// 可以看到使用global指示的变量是全局变量a,所以输出值为3
3 编译过程
C++代码的编译主要包括以下几个步骤:
- 预处理(preprocessing):预处理器(如GCC中的cpp)会处理代码中的预处理指令(如 #include 和 #define),并生成新的源代码文件;
- 编译(compilation):编译器(如GCC中的cc1)会将预处理后的源代码编译为汇编代码;
- 汇编(assembly):汇编器(如GCC中的as)会将汇编代码转换为机器码;
- 链接(linking):链接器(如GCC中的
ld
)会将多个机器码文件链接在一起,生成可执行文件。
3.2 Ninja的构建过程底层是调用gcc实现的吗?
- Ninja 是一种跨平台的构建管理工具(CLion中称为 Build Tool),它可以与各种编译器和链接器配合使用。所以,Ninja 的构建过程底层可以调用 GCC 实现,不过也可以调用其他编译器实现,这取决于构建项目时使用的编译器和链接器。
- 如果使用GCC和Ninja来构建项目,那么Ninja会读取构建脚本并调用 GCC 中的各个工具来完成预处理、编译、汇编和链接等步骤。
- Ninja 主要是用来管理和优化整个构建过程,而自身并不会执行编译和链接操作。
3.3 Ninja构建时的“断点续传”特性
Ninja在构建项目时具有一种类似于“断点续传”的特性:
- 在构建项目时,会根据输入文件和依赖关系生成一个任务图(task graph),然后按照任务图中的顺序依次执行各个任务。如果在某个任务执行过程中出现了错误,例如编译错误或链接错误,那么ninja会停止执行后续的任务,并输出错误信息;
- 在这种情况下,如果你修正了错误并重新运行ninja,它会自动从出错的任务继续执行,而不是从头开始构建整个项目。这是因为ninja会将任务图保存到一个文件中,如果任务图没有发生变化,ninja就会直接从保存的任务图中加载任务信息,而不需要重新扫描输入文件和依赖关系。这种机制可以大大加快项目的构建速度,特别是对于大型项目来说。