c++ - ODR 的目的是什么?

标签 c++ language-design linkage one-definition-rule

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

我看到违反它的两个后果——用户会得到语法错误,这完全没问题。并且还可能存在一些 fatal error ,并且用户将再次成为唯一有罪的人。

作为违反 ODR 并出现一些 fatal error 的示例,我想像这样:

a.cpp

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

main.cpp

struct A
{
        int a;
        int b;

};
void f(A a);

int main()
{

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

        return 0;
}

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

那么,ODR是在试图禁止用户做这种有害的事情吗?我不这么认为。

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

还有什么?

最佳答案

ODR 决定了哪些 C++ 程序是良构的。 ODR 违规意味着您的程序格式错误,并且标准没有规定程序将做什么,是否应该编译等。大多数 ODR 违规都被标记为“不需要诊断”,以使编译器编写者的工作更容易。

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

编译器可以随意获取您的代码并将其编译为 c: 格式。或其他任何东西。它可以免费检测 ODR 违规,并用它来证明代码分支无法运行,并消除导致那里的路径。

关于c++ - ODR 的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38030754/

相关文章:

c++ - 使用 boost asio 时如何获取 UDP 远程端点?

c++ - 为什么使用 std::vector 而不是 realloc?

C++显式关键字导致编译错误: template in template type cannot be resolved?

C - 在什么情况下外部声明成为定义?

c - 允许 "overriding"具有内部链接的零初始化对象

C++:memcpy 是基于 POD 的子对象 UB 吗?

string - 为什么流行的编程语言不使用其他字符来分隔字符串?

c# - 为什么 is 关键字需要非空表达式?

c# - 为什么我不能在 C# 中使用抽象静态方法?

c++ - 用说明符extern声明的C++中的标识符链接