安全地返回 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说它是一个"局部临时对象"。真的没有什么应该有一个本地临时对象,如果clang认为是这样的,并且在这个函数运行时正在删除东西,我想知道为什么。
标准是否保证这个函数返回的引用(在选择"def"的情况下)将与传入的引用具有相同的生命周期,或者是否允许将它们视为具有不同生命周期的两个不同引用?
不,不安全。
在本例中,三元条件操作符的计算结果为其操作数的副本。因此出现了警告。
你可以通过注入一个漂亮的小std::ref
来解决这个问题。
[C++11: 5.16/6]:
第二个和第三个操作数具有相同的类型;结果就是这种类型。如果操作数具有类类型,则结果是结果类型的右值临时值,根据第一个操作数的值从第二个操作数或第三个操作数复制初始化。
def
不是这里的临时对象。如果getValue
实际返回const String&
,则条件运算符也不会生成临时对象。
然而,这个函数的设计是危险的,因为它没有针对这样的错误的保护:
const String &bar = getValueAsString( "bla", "" ); // oops
从""
创建的临时字符串在getValueAsString
返回时死亡,因此bar
现在是一个悬垂引用(当然,如果触发了默认值)。
生命周期扩展仅在将临时对象直接绑定到引用时发生。从该引用初始化其他引用不会重新延长临时对象的生存期。
可能clang实际上检测到你的代码确实包含这个错误,即你在调用这个函数时绑定了一个临时的def
- 被解释为低级别const的const对象的地址
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- Google Or-Tools Glop:如何创建指向 const 对象的指针数组?
- 我们可以有一个 setter 成员函数作为从 const 对象引用的 const 吗?
- "this"指向的对象是否与 const 对象相同?
- 从 const 对象访问非 const 方法
- 将非 const 对象用于 const 参数
- 如何键入用于const对象的自定义io操纵器
- 哪个 const 与哪个引用将更改参数并创建一个 const 对象?
- 无法在返回中转换 const 对象
- 接受对 const 对象的引用但没有 r 值的函数
- 当我调用 main 中使用 const 对象的 const 函数时,不断出现错误
- 在 const 对象上调用非 const 函数
- 正确的方法通过巨大的const对象的向量
- 如何重载 const 对象的 [],以便值赋值不会导致编译错误
- 相互引用的 Const 对象
- 析构函数是否可以在 const 对象上调用非 const 函数
- decltype 不会推断 const 对象的 const 成员
- 防止const函数被调用非const对象
- constexpr引用非const对象