Gau*_*ant 0 c++ linker-errors language-lawyer
根据一个定义规则,类和结构定义不得在单个翻译单元中重复。
但是,为什么这样的话,如果它们实际上是定义,则允许以多个翻译单元重复它们。在这种情况下,链接器为什么不引发多定义错误?
例如-以下操作应通过相同的逻辑引发多个定义错误
测试
#ifndef TEST
#define TEST
class s {
int a;
int b;
};
#endif
Run Code Online (Sandbox Code Playgroud)
test1.cpp
#include "test.h"
int main() {}
Run Code Online (Sandbox Code Playgroud)
test2.cpp
#include "test.h"
Run Code Online (Sandbox Code Playgroud)
但是,为什么这样的话,如果它们实际上是定义,则允许以多个翻译单元重复它们。
在语言级别,答案很简单:因为标准是这样说的,特别是在[basic.def.odr] / 6中
一个类类型,枚举类型,具有外部链接的内联函数([dcl.inline]),具有外部链接的内联变量([dcl.inline]),类模板,非静态函数模板,类模板的静态数据成员,类模板的成员函数或未在程序中指定某些模板参数([temp.spec],[temp.class.spec])的模板专门化,前提是每个定义都出现在提供不同的翻译单位,并且定义满足以下要求。[…]
当然,有一定的原因可以说明为什么语言规则如此。在实现级别,类的定义仅告诉编译器在各个类类型的对象上运行的代码如何进行业务,例如,对象在对象中的位置等。但是类定义本身并不能真正生成代码。编译器必须查看使用该类的每个翻译单元中每个类类型的定义,以便编译器可以为每个翻译单元独立生成正确的代码。还必须在每个翻译单元中对类类型进行定义,以使为每个翻译单元生成的代码与为所有其他翻译单元生成的代码兼容。
在这种情况下,链接器为什么不引发多定义错误?
最后在符号级别工作的链接器只能看到生成的目标代码。而且类定义在机器代码级别没有明确的表示形式。在这个级别上,类的概念并不存在。它们以代码运行的方式而不是直接在代码中找到。如果您愿意的话,他们生活在装配线之间。
| 归档时间: |
|
| 查看次数: |
108 次 |
| 最近记录: |