未分配返回未定义对象类型引用的 C++ 函数的返回值时会发生什么情况
What should happen when the return value from a C++ function that returns a reference of an undefined object type is not assigned?
请考虑以下代码:
class Foo;
Foo& CreateFoo();
void Bar()
{
CreateFoo();
}
在 Visual Studio 中,这将导致错误 C2027,指出 Foo 是未定义的类型。在大多数其他编译器中,它可以很好地编译。只有当 CreateFoo 的返回值没有赋值时,这才是一个问题。如果我将行更改为:
Foo& foo = CreateFoo();
它在Visual Studio中编译得很好。此外,如果 Foo 是定义的而不仅仅是前向声明的,那么它将在没有赋值的情况下编译得很好。
哪个应该是正确的行为?C++标准中是否有任何内容可以解决这个问题,或者这是留给实现的东西?我看了看,没有看到任何关于这个的东西。
更新:已提交错误报告。
看起来像标准的相关部分(第 5.2.2 节):
如果结果类型是左值引用由于此函数结果类型是左值类型或函数的右值引用,则函数调用为左值 type,如果结果类型是对对象类型的右值引用,则为 x值,否则为 prvalue。
如果函数调用是对象类型的 prvalue:
如果函数调用为
描述符的操作数或
逗号运算符的右操作数,即 decltype-说明符的操作数,
不会为 PR值引入临时对象。 prvalue 的类型可能不完整。 [ 注意:因此,存储不会为 prvalue 分配,也不会被销毁;因此,类类型是 由于是此上下文中的函数调用类型而未实例化。无论 表达式是使用函数调用表示法还是运算符表示法 (13.3.1.2)。 — 尾注 ] [ 注: 与考虑 ID 表达式是否用括号括起来的 decltype-specifier 的规则不同 (7.1.6.2), 括号在这方面没有特殊含义。 — 尾注 ]
- 否则,PR值的类型应完整。
引用类型,因此函数调用的计算结果为左值,并且完整性要求不适用。
该代码是合法的,至少在 C++11 中是合法的,没有已发布的 Visual C++ 版本完全实现。
您始终可以在函数声明中使用不完整的类型(因为这只声明函数的签名,而不是任何实际代码),但在使用它时则不能。
调用CreateFoo();
等于(void) CreateFoo();
,我的猜测是Visual Studio需要检查Foo的代码才能进行任何转换(我不确定您是否真的可以编写无效转换),因为对于转换,您需要一个完整的类型。
至于 Foo & foo = CreateFoo();
,这不会进行任何转换,因此您可以摆脱不完整的类型。
- 当我使用 void 函数的返回值(通过强制转换函数指针)时,究竟会发生什么?
- 如何在不使用临时变量的情况下取消引用返回指针的函数的返回值?
- G++ 编译器是否在未使用返回值的情况下将 constexpr 函数视为常规函数?
- 对于具有引用返回类型的搜索算法,默认返回值应该是什么?
- 如何在没有返回值的情况下使用(特征)unaryExpr 和 lambda 函数?
- 使用 Google 基准测试时返回值会发生什么情况?
- 私有在函数定义/实现的返回值范围内是什么意思 (c++)?
- CUDA返回值错误35的含义是什么
- 串行读取()不会在没有数据接收的情况下返回值
- 如何在不返回 C++ 值的情况下退出 int 函数?
- 是什么意思,返回值是一个类名,后跟一对空括号
- "警告:并非所有控制路径都返回值"是什么意思?(C++)
- 为循环中多次调用的函数返回值预分配内存的正确方法是什么
- 在没有返回值优化的情况下将两个对象加在一起时,将创建多少个临时对象
- 将右值分配给'const auto&'时会发生什么情况
- 如果我不将其存储在任何地方,返回值会发生什么情况?
- 如果参数传递两次,会发生什么情况?一次按值,一次按引用?是否会修改
- 当运算符尝试输入大于变量可以包含的值>>会发生什么情况?
- C++ - 在线程中使用时,将函数的返回值声明为 void/void* 之间有什么区别吗?
- 未分配返回未定义对象类型引用的 C++ 函数的返回值时会发生什么情况