【问题标题】:Non-const reference bound to temporary, Visual Studio bug?非常量引用绑定到临时的 Visual Studio 错误?
【发布时间】:2025-12-01 16:40:01
【问题描述】:

我在gcc 中编译一些可移植代码时遇到了这个问题。基本上这个奇怪的代码在 Visual Studio 中编译,这真的让我大吃一惊:

class Zebra {int x;};
Zebra goo() {Zebra z; return z;}
void foo(Zebra &x)
{
    Zebra y;
    x = y;
    foo(goo());
}

Visual studio 让这个飞起来。 gcc 会将其捕获为编译错误。有趣的是,如果你将 Zebra 输入为 int,VC++ 会抱怨。相当矛盾的行为。想法?

【问题讨论】:

  • 这不是一个错误,它是一个编译器扩展,而且是一个邪恶的扩展。
  • MSVC 确实有 warning C4239: nonstandard extension used,但显然您已关闭该警告。
  • 我不明白你为什么需要使用无限递归函数来演示这个。

标签: c++ visual-studio temporary-objects


【解决方案1】:

这是 Visual Studio 的旧扩展,我可以在 Microsoft 网站上找到的唯一参考是这个错误报告:Temporary Objects Can be Bound to Non-Const References,其中包含以下示例代码:

struct A {};

A     f1();
void f2(A&);

int main()
{
    f2(f1()); // This line SHALL trigger an error, but it can be compiled without any     errors or warnings.
}

回复说明之一:

有一个 4 级警告(如果您将 /W4 传递给编译器,则启用 4 级警告)

这篇博文:Visual C++ is so Liberal 涵盖了这个扩展,并指出:

使用禁用语言扩展 (/Za) 会导致错误:

【讨论】:

    【解决方案2】:

    正如其他人所说,这是由于 Microsoft C++ 扩展。虽然不推荐使用/Za 标志,因为它会破坏事物。

    改为使用/permissive- 开关以获得更好的标准合规性,您将在这些情况下得到健康的错误。请注意,此标志自 VS 2017 起可用。

    开关 /Za 不支持某些关键的 Microsoft SDK 头文件。相比之下,/permissive- 提供了一种有用的一致性模式,其中输入的 C++ 代码根据 ISO C++ 规则进行解释,但也允许在 Visual C++ 支持的目标上编译 C++ 所需的一致性扩展。

    更多信息请访问Visual C++ Team Blog

    【讨论】:

    • 可能值得注意的是,/permissive 标志自 VS 2017 起可用。您可以通过包含文章中的相关引用来改进此答案。就像什么一样,为什么被介绍以及它与/Za的关系
    最近更新 更多