return const & 对 const & 传递的对象安全吗?

Safe to return const & to object passed by const &?

使用 clang-3.5 将以下代码编译为 C++11 标准时:

const String& XMLAttributes::getValueAsString(const String& attrName, const String& def) const
{
    return (exists(attrName)) ? getValue(attrName) : def;
}

我收到以下警告:

warning: 
  returning reference to local temporary object [-Wreturn-stack-address]
    return (exists(attrName)) ? getValue(attrName) : def;
                                                     ^~~
note: 
  binding reference variable 'def' here
  ...String& attrName, const String& def) const
                                 ^
1 warning generated.

g++-4.9没有给出类似的警告。

我认为 clang 过于热心,在这种情况下它应该可以正常工作,因为我知道当使用此函数时,输入具有足够长的生命周期。 (我很确定我已经看到了大量似乎以这种方式工作的代码......)

虽然 clang 说它是 "local temporary object",但我有点害怕。真的没有什么应该有一个本地临时对象,如果 clang 这么认为并且正在删除东西,而这个函数是 运行 我想知道为什么。

标准是否保证此函数返回的引用(在选择 "def" 的情况下)将与传入的引用具有相同的生命周期,或者是否允许它们可以被认为是具有不同生命周期的两个不同引用?

不,这不安全。

在这种情况下,三元条件运算符计算为其操作数的副本。因此警告。

您可能可以通过注入一个不错的小 std::ref 来解决它。

[C++11: 5.16/6]: The second and third operands have the same type; the result is of that type. If the operands have class type, the result is a prvalue temporary of the result type, which is copy-initialized from either the second operand or the third operand depending on the value of the first operand.

def 在这里不是临时对象。如果 getValue 实际上 returns const String& 那么条件运算符也不会生成临时对象。

但是这个功能设计是危险的,因为没有针对这样的错误的保护:

const String &bar = getValueAsString( "bla", "" );   // oops

"" 创建的临时字符串在 getValueAsString returns 时消失,因此 bar 现在是一个悬空引用(当然,如果触发了默认值)。

仅当临时对象直接绑定到引用时才会延长生命周期。从该引用初始化其他引用不会重新延长临时文件的生命周期。

可能 clang 实际上检测到您的代码确实包含此错误,即您在某个时候调用此函数时将临时绑定到 def