编译器相关
迪丽瓦拉
2024-06-02 23:44:01
0

ODR

全称:one definition rule

定义:ODR是一系列规则

基本上,每个变量、函数、概念、类、模板(C++20)在每个转换单元中只允许一个定义。

特别注意*:非inline的函数或变量(C++17)在整个程序中有且只有一个定义

例外

const、static、inline这三个声明定义的变量或函数都能有多个定义

转换单元

定义:我们写好的每个源文件,将其所包含的头文件合并后,称为一个转换单元

翻译器将每一个转换单元生成对应的obj文件(obj文件即对象文件),obj文件包含了转换单元的机器码和引用信息,引用信息包括在这个转换单元内定义的对象和不在这个转换单元内定义的对象

最后链接器将各个转换单元的obj文件链接起来,生成目标程序

如果在对象文件A中包含了定义在其他转换单元中的引用,那么链接器就会去转换单元中找这个引用的定义来建立链接,如果找不到,就会生成一个链接错误的指令

extern void test();
int main()
{test();
}

这里就会生成一个链接错误的指令LNK201

未定义行为

含义:C++标准未定义的行为

未定义行为的结果是不确定的,在不同编译器下有不同的结果

如c=2*a+++++a*4

这里是先运算a++呢还是先运算++a呢

又如int a=-12345

a>>2

这里右移前面是补1还是补0,在不同编译器下有不同结果

链接器

名称的链接属性

程序中的变量、函数、结构都有自己的名称,这些名称有不同的链接属性,连接器就是通过这些属性把对象文件链接起,名称不能相同,不然链接会发生模糊

链接属性的分类

内部链接属性:该名称仅仅在本链接单元中有效

外部链接属性:该名称在其他链接单元中也有效

无链接属性:该名称仅在作用域中有效

内部链接属性关键字有:static、const,不包括inline。可以通过static声明一个函数仅供本转换单元内使用,但是标准委员会不推荐这样做

外部链接属性关键字有:extern

inline和static的区别

在教程中,有以下代码

a.cpp

inline int a=100;
void func()
{std::cout<

b.cpp

inline int a=200;
void func();
int main()
{func();
}

教程中结果输出200,但是我自己实践后,发现结果是100?所以这里就不多讲了,因为我也不知道原因,也提问了,回答都不尽人意。教程还提到了inline所声明的函数共用内存空间,static声明的函数有各自的内存空间,这句话对错还需自己斟酌

特别注意*:inline一般可以用在头文件中声明变量,因为如果有重复变量,还是会使用本转换单元中的值,

相关内容