ODR的目的是什么?

Mis*_*ody 1 c++ language-design one-definition-rule linkage

我确实理解ODR所说的内容,但我不明白它试图实现的目标.

我看到违反它的两个后果 - 用户将得到语法错误,这是完全正常的.并且可能存在一些致命的错误,并且用户将是唯一一个有罪的人.

作为违反ODR并获得致命错误的例子,我想像这样:

a.cpp

struct A
{
        int a;
        double b;
};
void f(A a)
{
        std::cout << a.a << " " << a.b << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

struct A
{
        int a;
        int b;

};
void f(A a);

int main()
{

        A a = {5, 6};
        f(a);

        return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果示例与ODR无关,请纠正我.

那么,ODR是否试图禁止用户做这些有害的事情?我不这么认为.

是否试图为编译器编写者设置一些规则,以避免潜在的危害?可能不会,因为大多数编译器都没有检查ODR违规.

还有什么?

Tay*_*wee 5

当函数期望得到这些结构中的一个时,你将它重新声明为不同的东西,该函数接收哪个结构,以及如何?请记住,C++是静态的,因此如果按值发送结构,则函数必须知道它的结构.因为C++是类型安全的,允许违反ODR会违反这种类型的安全性.

最重要的是,缺乏ODR会有什么好处?我可以想到数以百计的事情,如果没有它就会变得更难,也无法获得.从能够在同一名称空间中踩踏先前声明的类型实际上没有灵活性.在最好的情况下,它只会使多个包含不需要标题保护,这是一个非常小的收益充其量.


Yak*_*ont 5

ODR决定了C++程序的良好形成.ODR违规意味着您的程序格式不正确,并且标准没有规定程序将执行什么操作,是否应该编译等.大多数ODR违规都标记为"无需诊断",以使编译器编写器的工作更容易.

这允许C++编译器对您提供的代码做出某些简化的假设,就像::A在任何地方都是相同的结构类型,而不必在每个使用点检查.

编译器可以自由地获取代码并将其编译为格式化c:.或其他任何东西.它可以自由检测ODR违规,并使用它来证明代码分支无法运行,并消除了导致那里的路径.