2012-02-21 94 views
-1
int& lameness() 
{ 
    int h=66; 
    return h; 
} 
int main() 
{ 

    int c; 
    c = lameness(); 
    cout<<"c is "<<c<< endl; 
    system("pause"); 
    return 0; 
} 

这是为什么能正常工作? int h是一个局部变量,不应该在它退出函数作用域时被销毁?C++简单引用类型函数

如果我将我的功能更改为此,它将在没有警告的情况下运行。这是否安全? :

int& lameness() 
{ 
    int h=66; 
    int &a = h; 
    return a; 
} 

回答

1

它不起作用。这是未定义的行为。你的怀疑是正确的:lameness函数是一个错误,一些编译器会这样标记它。尽管如此,编译器可能“符合”并仍然“允许”此代码......这就是C和C++的“跛脚”。

1

它被破坏。它正好可以工作,因为存储在h中的内存在打印值时未被覆盖。

4

是的。但关于未定义行为的奇妙之处在于,实际发生的是...未定义。销毁一个int实际上并不涉及任何事情,因此如果没有任何东西在堆栈上重复使用,那么值仍然会存在。这就是让这种事情如此令人沮丧的原因 - 通常它似乎起作用,直到你做出一些看起来不相关的小变化,并且它停止工作!

1

它只适用于你的巧合,因为你的代码在做任何事情之前需要在引用中的值的副本。它不保证工作。

你可以看到它与失败:

#include <iostream> 
using namespace std; 
int& lameness() 
{ 
    int h=66; 
    return h; 
} 
int main() 
{ 
    int &c = lameness(); 
    cout << "c is " << c << endl; 
    return 0; 
} 

当然,我不得不忽视编译警告:

x.cpp: In function ‘int& lameness()’: 
x.cpp:5:13: warning: reference to local variable ‘h’ returned [enabled by default] 
x.cpp: In function ‘int main()’: 
x.cpp:12:28: warning: ‘h’ is used uninitialized in this function [-Wuninitialized] 

产量为:

c is 0 

这是因为通过将时间c传递给I/O系统,该空间曾经是已在其他变量中重复使用,lameness(),因此抓取存储在该空间中的66。事实上,即使您的原始代码在我的机器上产生了0。