Return局部变量的引用
Return the reference of the local variable
在下面的代码中,演示了两个函数。 f1() returns函数作用域中初始化局部变量的引用,f2()returns函数作用域中初始化局部变量的值。
f2() 预计会很好地工作,因为本地初始化变量。值从堆栈传递到 main。
f1() 预计不会工作,因为局部变量的引用在函数范围之外是无用的。但是,这两个函数的输出似乎都可以。
这里是测试代码;
#include <iostream>
using namespace std;
// function declarations
int& f1();
int f2();
int main()
{
cout << "f1: " << f1() << endl; // should not work!
cout << "f2: " << f2() << endl; // should work
return 0;
}
int& f1() // returns reference
{
int i = 10; // local variable
return i; // returns reference
}
int f2() // returns value
{
int i = 5; // local variable
return i; // returns value
}
输出结果如下;
f1: 10
f2: 5
为什么即使 f1() returns 引用局部变量,f1() 也能正常工作?
超出范围访问局部变量是未定义的行为。未定义的行为意味着程序可能会运行,它可能会出现段错误,它可能会打印垃圾值,一切。
底层原因1是局部变量位于堆栈上。堆栈属于进程的可写地址 space(至少在大多数(如果不是全部)像您这样的操作系统上是这样的)。程序可能会随心所欲地写入它。 但是,C++ 不支持写入堆栈。 C++ 只定义局部变量,不定义调用帧或 return 地址。它驻留在更高的抽象层次上。我所知道的唯一支持直接写入堆栈的语言是 Assembly。
1 C++ 标准没有以任何方式指定这个原因。
欢迎使用未定义的行为!
这就是你正在做的。您访问了一个超出范围的变量。但是,可能是系统没有在已经存在的值上写一些东西,这解释了行为。
这就是为什么很难在实际代码中找到这样的逻辑错误。因为您可能(不)幸运并且变量具有正确的值(在该特定执行中)。
因此,f1()
的 return 值是对超出范围的内容的引用,而 f2()
的 return 值是对的副本该函数的局部变量,可以。
然而,下降编译器应该警告你这一点,警告是这样的:
warning: reference to local variable ‘i’ returned [-Wreturn-local-addr]
请在编译器中启用 警告标志。 :)
在下面的代码中,演示了两个函数。 f1() returns函数作用域中初始化局部变量的引用,f2()returns函数作用域中初始化局部变量的值。
f2() 预计会很好地工作,因为本地初始化变量。值从堆栈传递到 main。
f1() 预计不会工作,因为局部变量的引用在函数范围之外是无用的。但是,这两个函数的输出似乎都可以。
这里是测试代码;
#include <iostream>
using namespace std;
// function declarations
int& f1();
int f2();
int main()
{
cout << "f1: " << f1() << endl; // should not work!
cout << "f2: " << f2() << endl; // should work
return 0;
}
int& f1() // returns reference
{
int i = 10; // local variable
return i; // returns reference
}
int f2() // returns value
{
int i = 5; // local variable
return i; // returns value
}
输出结果如下;
f1: 10
f2: 5
为什么即使 f1() returns 引用局部变量,f1() 也能正常工作?
超出范围访问局部变量是未定义的行为。未定义的行为意味着程序可能会运行,它可能会出现段错误,它可能会打印垃圾值,一切。
底层原因1是局部变量位于堆栈上。堆栈属于进程的可写地址 space(至少在大多数(如果不是全部)像您这样的操作系统上是这样的)。程序可能会随心所欲地写入它。 但是,C++ 不支持写入堆栈。 C++ 只定义局部变量,不定义调用帧或 return 地址。它驻留在更高的抽象层次上。我所知道的唯一支持直接写入堆栈的语言是 Assembly。
1 C++ 标准没有以任何方式指定这个原因。
欢迎使用未定义的行为!
这就是你正在做的。您访问了一个超出范围的变量。但是,可能是系统没有在已经存在的值上写一些东西,这解释了行为。
这就是为什么很难在实际代码中找到这样的逻辑错误。因为您可能(不)幸运并且变量具有正确的值(在该特定执行中)。
因此,f1()
的 return 值是对超出范围的内容的引用,而 f2()
的 return 值是对的副本该函数的局部变量,可以。
然而,下降编译器应该警告你这一点,警告是这样的:
warning: reference to local variable ‘i’ returned [-Wreturn-local-addr]
请在编译器中启用 警告标志。 :)