二三、编译器
二三、编译器1、One Definition Rule
1)转化单元
我们写好的每个源文件(.cpp,.c)将其所包含的头文件(#include )合并后,称为一个转化单元。
编译器单独的将每一个转化单元生成为对应的对象文件(.obj),对象文件包含了转化单元的机器码和转化单元的引用信息(不在转化单元中定义的对象)。
最后链接器将各个转化单元的对象文件链接起来,生成我们的目标程序。
比如在对象文件A中包含了定义在其它转化单元的引用,那么就去其它转化单元的对象文件中寻找这个引用的定义来建立链接,如果在所有的对象文件中都找不到这个定义,那么就会生成一个链接错误。
2)未定义行为
在编写代码中,C++标准未做规定的行为,称为未定义行为,未定义行为的结果是不确定的,具体不同的编译器下会有不同的效果,比如
c=2*a++ + ++a*6;
这里先算a++还是先算++a就是一个未定义行为,比如
int x = -25602;
x= x>>2;
x的结果在不同的编译器下是不确定的,因为这也属于未定义行为
3)One Definition Rule(ODR)
ODR是一系列规则,而不是一个规则,程序中定义的每个对象都应有着自己的规则;但是基本上来讲任何的变量、函数、类、枚举、模板、概念(C++20)在每个转化单元中都只允许有一个定义;
在整个程序中,非inline的函数或变量(C++17),有且仅能有一个定义
const声明的变量或函数只在当前的源文件中有效,可以在一个项目的不同源文件定义相同的const变量
4)名称的链接属性
程序中的变量、函数、结构等都有着自己的名字,这些名字具有不同的链接属性,链接器就是根据这些链接属性来把各个对象文件链接起来的。链接属性分为以下三种
①内部链接属性:该名称仅仅在本转化单元中有效,如static、const声明的变量、函数
②外部链接属性:该名称在其它转化单元中也有效。通过extern关键字可以定义外部链接属性
③无链接属性:该名称仅仅能够用于该名称的作用域内访问
注:static变量或函数在自己的转化单元有着自己的内存空间,而inline定义的变量只有一个内存地址
2、#define
1)用法一
#define A B //将标识符A定义为B的别名
#define 整数 int //将整数替换为int
整数 a{};//#define实际用法#include #define _HHHH_ int a//将_HHHH_ 替换为int a#define VERSION "V2.0"int main(){ _HHHH_ { 250 }; std::cout
页:
[1]