c++ - 为什么结构和类定义可以在多个翻译单元上重复?

标签 c++ language-lawyer linker-errors

<分区>

根据单一定义规则,类和结构定义不得在单个翻译单元中重复。

但是,如果它们实际上是定义,那么为什么允许它们在多个翻译单元中重复出现。为什么在那种情况下链接器不抛出多重定义错误?

例如- 下面应该按照相同的逻辑抛出多重定义错误

测试.h

#ifndef TEST
#define TEST

class s {
  int a;
  int b;
};

#endif

测试1.cpp

#include "test.h"

int main() {}

测试2.cpp

#include "test.h"

最佳答案

But then why is the case that they are allowed to be repeated in multiple translation units, if they are in reality definitions.

在语言层面,答案很简单:因为标准是这么说的,特别是在 [basic.def.odr]/6 中。

There can be more than one definition of a class type, enumeration type, inline function with external linkage ([dcl.inline]), inline variable with external linkage ([dcl.inline]), class template, non-static function template, static data member of a class template, member function of a class template, or template specialization for which some template parameters are not specified ([temp.spec], [temp.class.spec]) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. […]

当然,语言规则之所以如此,是有原因的。在实现层面,类的定义只是告诉编译器,对相应类类型的对象进行操作的代码必须如何处理业务,例如,对象成员位于何处等。但是类定义本身并不会真正生成代码。编译器有必要在使用该类的每个翻译单元中查看每个类类型的定义,以便它可以独立地为每个翻译单元生成正确的代码。类类型的定义在每个翻译单元中也必须相同,以便为每个翻译单元生成的代码与为所有其他翻译单元生成的代码兼容。

Why doesnt the linker throw a multiple definition error in that case ?

在符号级别工作的链接器最终只能看到生成的目标代码。并且类定义在机器代码级别没有明确的表示。类的概念在那个级别上并不真正存在。它们存在于代码运行的方式中,而不是直接存在于代码中。如果你愿意,他们可以生活在装配线之间……

关于c++ - 为什么结构和类定义可以在多个翻译单元上重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55486965/

相关文章:

c++ - 在内存中创建进程 C++

c++ - Vector 不会存储正确的数据类型(wchar_t 而不是 uint16_t)

c++ - 何时在编译时评估constexpr?

c++ - (&const_object) 可以评估为临时地址

c - Linux 上 CLion 中的数学库链接错误

Linux FreeBSD共享对象问题

c++ - 如何将 "int X::*"的内部 typedef 作为模板函数参数传递?

c++ - 将模板类作为 arg 参数传递给 std::bind

c++ - 在需要 sudo 运行的 NetBeans 8.0 中调试 C++ 程序

c - 普通 int 上的 stdatomic.h 函数 - 产生未定义或实现定义的行为?