【问题标题】:Why does one-definition-rule-use (odr-use) depend on the context?为什么单一定义规则使用(odr-use)取决于上下文?
【发布时间】:2016-10-19 03:19:10
【问题描述】:

给定以下代码:

#include <iostream>

struct A {
    static constexpr float a = 2.0f;
};

// non-const reference to make it more explicit - same behaviour
template<class T> constexpr inline T square(T& x)
{
    return x * x;
}

int main() {
    /*constexpr*/ float val = square(A::a);
    std::cout << val;
}

该程序无法与undefined reference to 'A::a' 链接(总是与clang,仅在-O0 与g++ 上),但是如果我从val 声明中取消注释constexpr,它会正确链接。

到目前为止,我知道如果没有在其中一个单元文件中明确定义,constexpr 不能被 odr-使用,但我不明白为什么它在分配给 constexpr 时会起作用。

似乎这两种情况的处理方式因上下文而异。但为什么?在这两种情况下,编译器不应该只在编译时评估这个函数吗?

【问题讨论】:

  • 您发布的 sn-p 在 GCC 和 CLANG 中都能正常编译。
  • 请不要在标题中使用不常见的首字母缩略词。
  • 到底什么是“单一定义规则使用”?
  • @Andrew ...这完全没有抓住重点。我知道什么 odr-use 很好。
  • @UmNyobe:“odr-use”是 C++ 标准中的一个技术术语。这可能是不寻常的,但它是准确的,并且它是您可以在索引中查找的内容,与展开的形式不同。

标签: c++ c++11 constexpr one-definition-rule


【解决方案1】:

为什么 odr-use 取决于上下文?

它没有。 square(A::a) odr-uses A::a,句号。

然而,大多数 ODR 违规都不需要被诊断出来,这也不例外。

编译器不应该在两种情况下都在编译时评估这个函数吗?

constexpr 变量的初始化程序必须在编译时进行评估。 (嗯,不完全是,但是编译器必须将它评估到它可以确定它是一个有效的常量表达式的程度,此时它还不如只做整个事情。)对于非constexpr 本地变量,没有这样的保证。

【讨论】:

  • 所以我宁愿问:“为什么 odr-use 在编译时起作用?”。例如,指针指向哪里?程序没有运行。它是否指向一些编译器结构?为什么在这种情况下它不会简单地失败?为什么标准允许这样的构造?
  • @pkubik 当然,您可以创建一个提出该问题的问题。让它更精致一点,并把它附加到一个真正的问题上,理想情况下。然而,这个问题不是那个!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 2023-04-08
  • 2020-10-26
相关资源
最近更新 更多