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
。
使用 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
。