gpt4 book ai didi

c++ - C++ 模块是否不存在 ODR 违规?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:37:44 24 4
gpt4 key购买 nike

来自N4720 C++ 模块草案,[basic.def.odr]/6 说:

[…] For an entity with an exported declaration, there shall be only one definition of that entity; a diagnostic is required only if the abstract semantics graph of the module contains a definition of the entity. [Note: If the definition is not in the interface unit, then at most one module unit can have and make use of the definition. — end note] […]

根据我的理解,这实际上使模板有机会只被编译器解析一次,这与当前的情况形成对比(每个翻译单元都有其定义的精确拷贝)。这也适用于具有类似大小写的其他实体,例如内联函数/变量。

我的问题是由于每个翻译单元最多只能有一个实体定义(如 [basic.def.odr]/1 中所述),因此跨 TU 对实体的不同定义是未定义的行为。而且,由于导出的实体在整个编译单元中只有一个定义(使未导出的实体在其实现单元中是唯一的),从我的角度来看,即使不是不可能,也很难弄错定义。

最后,简单地说:模块的使用是否会(或确实或应该)使违反 ODR 规则变得不可能,或者更难出错?

最佳答案

如果一个项目是完全模块化的(也就是说,从不使用#include),那么大多数意外的 ODR 违规都会消失。大多数意外的 ODR 违规是由于 #include 的性质而发生的:包括带有定义的全局变量等等。或者两阶段模板查找问题,其中两个文件包含相同的模板,但由于每个文件在该模板之前包含的内容,所以两个模板的定义不同。

但是,这并不能防止不太“意外”的 ODR 违规。因为“同一实体”是由其名称定义的,而实体的名称与其导出的模块无关,因此两个模块可以提供同一实体的不同定义。所以基本上,名称冲突。

如果单个翻译单元同时导入这两个模块,这只会成为编译错误(即:需要诊断)。如果两个单独的翻译单元各自包含具有不同定义的模块之一,那么整个程序仍然违反 ODR,但不必对其进行诊断。

因此,即使在完全模块化的代码库中,ODR 仍然可能被违反。

关于c++ - C++ 模块是否不存在 ODR 违规?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48665890/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com