You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中返回绑定到临时对象的引用参数的引用导致悬垂引用的规则解析及编译器行为疑问

悬垂引用为何看似“正常工作”?拆解编译器实现与标准规则

Hey, that's a really interesting observation—let's unpack what's going on here, because what you're seeing is a perfect example of how undefined behavior (UB) can sometimes look like it's working as expected.

First: Why the standard says sum is a dangling reference

Let's recap the core rule: When a temporary is bound to a reference parameter of a function, its lifetime only lasts until the end of the full expression containing that function call. In your code:

X&& sum = a + b + c + d;
  • The first a + b creates a temporary X object.
  • Each subsequent operator+(X&&, const X&) takes that temporary's rvalue reference, modifies it, and returns a reference to it.
  • The full expression here is the entire chain a + b + c + d. Once this expression finishes, the temporary object that sum is bound to reaches the end of its lifetime—it doesn't get extended just because sum is referencing it, because this temporary was returned via a function reference, not directly bound to sum during initialization.

By the letter of the C++ standard, sum is absolutely a dangling reference, and accessing it is undefined behavior.

So why aren't compilers breaking your code?

This comes down to compiler implementation details, not any guarantee from the standard:

  • Most compilers (GCC, Clang, MSVC) allocate temporary objects like this in the current function's stack frame (in your case, main's stack frame). When you call anotherFunc, its stack frame is allocated on top of main's frame (since stacks grow downward on most systems). The big array in anotherFunc uses space in its own stack frame, which doesn't overlap with the temporary in main's frame.
  • Undefined behavior doesn't mean "your program must crash immediately"—it means the standard gives no guarantees about what happens. The compiler isn't required to actively overwrite or invalidate the memory of the expired temporary; if nothing else uses that memory location, the old data will just sit there.

If you tried a scenario where the compiler chose to allocate the temporary in a region that gets overwritten (e.g., a deeper call stack with larger allocations), you'd likely see crashes or garbage values.

Why Howard Hinnant warned about this for std::string

The reason std::string avoids this design is that relying on compiler-specific stack behavior is risky. Even if your test case works, there's no guarantee it will work across all compilers, optimization levels, or more complex program structures. The standard library prioritizes portability and correctness according to the standard, not relying on non-standard implementation quirks.


内容的提问来源于stack exchange,提问作者Ruperrrt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 04:03:15