【发布时间】:2020-02-15 13:53:35
【问题描述】:
我试图深入研究 inline 函数的含义,并偶然发现了这个问题。考虑这个小程序(demo):
/* ---------- main.cpp ---------- */
void other();
constexpr int get()
{
return 3;
}
int main()
{
std::cout << get() << std::endl;
other();
}
/* ---------- other.cpp ---------- */
constexpr int get()
{
return 4;
}
void other()
{
std::cout << get() << std::endl;
}
在没有优化的情况下编译时,程序会产生以下输出:
3
3
这可能不是我们想要的,但至少我可以解释。
- 编译器不需要在编译时计算
constexpr函数的结果,因此它决定将其推迟到运行时。 -
constexpr函数暗示inline - 我们的
get()函数恰好有不同的实现 - 我们没有将
get()函数声明为静态 - 链接器只能选择
get()函数的一种实现
碰巧链接器从main.cpp中选择了get(),返回3。
现在到我不明白的部分。我只是将get() 函数从constexpr 更改为consteval。现在编译器需要在编译期间计算该值,即在链接时间之前(对吗?)。我希望 get() 函数根本不会出现在目标文件中。
但是当我运行它时 (demo),我的输出完全相同!这怎么可能?.. 我的意思是,我知道这是未定义的行为,但这不是重点。为什么应该在编译时计算的值会干扰其他翻译单元?
UPD:我知道这个功能is listed as unimplemented in clang,但问题仍然适用。是否允许符合标准的编译器表现出这种行为?
【问题讨论】:
-
UB 意味着 anything 可能发生在程序的 any 部分。在尝试推理任何事情之前,首先摆脱任何 UB。
标签: c++ constexpr c++20 one-definition-rule consteval