2011-08-12 70 views
6

我只是建立我们的工作项目之一,我看到的是增加了一个新功能:警告C4172:返回一个绑定到局部变量的const std :: string引用。它有多安全?

const std::string& ClassName::MethodName() const 
{ 
    return ""; 
} 

,编译器会发出警告:

警告C4172:局部变量或临时的返回地址

我认为编译器是正确的。 这个功能有多安全?

请注意,函数不会返回const char*,因为字符串文字具有静态存储持续时间,所以这样做可以。它返回一个参考const std::string

回答

6

是的,它是不安全的。
返回本地变量或临时地址并解除引用会导致未定义的行为。

正如您所评论的:
是的,临时绑定到常量引用的生命周期增加到常量的生命周期。但是这需要调用者接受const引用中的返回值,因此函数本身并不安全。

从C++标准:
C++ 03 12.2临时对象

的第二上下文是当引用绑定到一个暂时的。临时到该参考结合或临时即完整的对象,该对象的临时结合持续除了下面指定的参考的寿命的子对象...

临时结合到构造函数的ctor-initializer(12.6.2)中的引用成员一直存在,直到构造函数退出。临时绑定到参数 参数在函数调用(5.2.2)中一直存在,直到包含该调用的完整表达式的完成为止。函数返回语句(6.6.3)中对返回值的临时绑定一直存在,直到函数退出

+0

我正在考虑延长临时绑定到const引用的生命周期...我的意思是,也许它***是安全的?在与开发人员交谈之前,我想确保添加了功能 –

+0

@Armen Tsirunyan,在您调用任何函数之前它是安全的。即使你不调用函数,也不能使用它,因为所有可以使用它的函数都是函数。即使你找不到任何函数来使用它,编译器可能会重新排列你的代码并在中间放置一个函数。所以它在任何方面都不安全 – Dani

+0

@Als:我不能说我对答案满意。如果一个本地临时***的生命周期不能超出其范围(我不知道是否是这种情况),那么你是对的,**但**在这种情况下绑定返回值该函数的const引用也无济于事。如果它可以在函数外部扩展,那么它是绑定它还是复制它是无关紧要的... –

3

做你做了什么,实际上是在编译器在内部做到这一点:

const std::string* ClassName::MethodName() const 
{ 
    std::string temp = ""; 
    return &temp; 
} 

并返回引用或指针到局部变量是坏的。

+0

它不仅坏 - 它* terribad *,未定义。 – Schnommus

1

这是做事情说清楚我的一个例子:

#include <iostream> 
using std::cout; 
struct A{ 
    A() { 
     cout << "Ctor\n"; 
    } 
    ~A() { 
     cout << "Dtor\n"; 
    } 
}; 

const A& f(){ 
    return A(); 
} 

int main(){ 
    const A& ref = f(); 
    cout << "1\n"; 
    { 
     const A& ref1 = A(); 
     cout << "2\n"; 
    } 
    cout << "3\n"; 
} 

输出

Ctor 
Dtor 
1 
Ctor 
2 
Dtor 
3 
+0

示例忽略了这一点。如果你在3之后访问ref,它会更有意义。 –

相关问题