【发布时间】:2015-04-14 21:25:52
【问题描述】:
我很难理解这段代码(来自 C++14 草案标准 [conv.lval] 的示例)如何调用 g(false) 的未定义行为。为什么constexpr 使程序有效?
另外,“不访问y.n”是什么意思?在对g() 的两次调用中,我们都返回了n 数据成员,那么为什么最后一行说它不能访问它呢?
struct S { int n; };
auto f() {
S x { 1 };
constexpr S y { 2 };
return [&](bool b) { return (b ? y : x).n; };
}
auto g = f();
int m = g(false); // undefined behavior due to access of x.n outside its
// lifetime
int n = g(true); // OK, does not access y.n
【问题讨论】:
-
我的猜测是
constexpr在编译时被评估并存储在程序的某个只读部分中,与堆栈帧无关,而x在堆栈帧中,并访问它删除堆栈帧后会导致未定义的行为。 -
你在哪里找到这个例子?在标准中,还是在其他来源中?
-
@BenVoigt 它来自 C++14 [conv.lval]/2.2。
-
@BenVoigt 您的 cmets 非常有帮助。实际上,由于我最近对 constexpr 和 ODR 提出的一些 SO 问题,我才开始深入研究 ODR 规则。相对较新的措辞不是直截了当的,那里的一些解释也不是很好。
-
@ShafikYaghmour:是的,我真的不喜欢“表达式的潜在结果”这个词,它与同一个表达式的“结果”完全无关。
标签: c++ language-lawyer c++14 constexpr lvalue-to-rvalue