C++23 悬空引用编译错误

问题描述 投票:0回答:1

以下显然会导致 C++23 中的编译错误:

int& f(int& x) {
    int y = ++x;
    return y;
}

错误

cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'

但是这个one似乎甚至没有给我们警告:

int& f(int x) {
    int &y = ++x;
    return y;
}

这在编译阶段很难捕获吗?

谢谢。

c++ reference c++23
1个回答
0
投票

为什么第一个示例无法编译,与第二个示例不同

要理解其中的差异,必须理解为什么代码无法在 C++23 中编译。 也就是说,在第一个示例中,

y
move-eligible,因为它命名了一个 隐式可移动实体 并出现在
return
语句中。因此:

如果表达式符合移动条件,则它是一个x值(见下文);如果实体是函数、变量,则为左值 [...]

- [expr.prim.id.unqual] p1

在第二个示例中,

y
没有命名隐式可移动实体,因此它被认为是左值,并且引用绑定成功。

第一个示例无法编译的事实不是,因为 C++ 委员会已努力检测悬空引用;相反,这只是当涉及到

return
语句中的隐式移动时,一些措辞更改的一个方便的副作用。

一般检测悬空引用

检测除此之外的悬空引用,微不足道的情况是非常困难的。它通常需要函数的生命周期注释,类似于 Rust。 有些提案至少专注于检测简单的案例。

例如,Herb Sutter 在P1179:终身安全:防止常见悬空中提出了基于非循环控制流图(ACFG)的标准化分析。这至少使得本地分析(在同一功能内)成为可能。该提案长达 47 页,这一事实表明这不是一个小问题。

© www.soinside.com 2019 - 2024. All rights reserved.