[C/C++] 函数返回值与返回局部对象的引用
[C/C++高手进] 函数返回值与返回局部对象的引用!主要有2个问题:大家都知道一条规则:不能返回局部对象的引
[C/C++高手进] 函数返回值与返回局部对象的引用!
主要有2个问题:
大家都知道一条规则:不能返回局部对象的引用。
而且编译器一般也会提示“reference to local variable returned"!
假设定义了类Test:
Test& f()
{
Test t;
t.i=1;
return t;
}
Test g()
{
Test t;
t.i=1;
return t;
}
int main()
{
Test t1=f(); //---(1)
Test t2=g(); //---(2)
}
比较语句(1)和语句(2):
语句(1)在调用f()函数后其栈空间被释放,但数据仍在栈中,而且不会因其它因素而导致数据损坏,因为当前栈帧为main函数的,栈顶指针比返回引用对象t的地址要高!
语句(2)很简单,但实际情况与想像的不一样。
第1个问题我的理解是:如果返回一个局部对象的引用,程序员能够确保不会对该引用的对象进行修改,只用来读取,那么即使是这种做法不好,也不会导致运行出错。同时,既然是只读应该返回const引用,这样就可以避免去修改引用的局部对象(当然,绕开编译器强行修改该对象除外)!
语句2,我通过汇编发现实际情况有点不同寻常。我不知道,编译器是否都做了优化,我是在LINUX X64 GCC下编译的。汇编代码的结果让我很吃惊:实际调用为:g(&t2);而函数g()变成了如下形式
void g(Test* t)
{
t->i=1;
}
语句2比语句1效率更高!!
PS:从另一方面也可以验证:语句(1)会调用复制构造函数;而语句(2)不会!!
第2个问题照样正常理解,语句2应该返回一个临时对象;如果返回临时对象,那么临时对象到底存放在栈的哪个位置(寄存器是不可能了,Test类大小大于8Bytes),g()函数栈都已经收回了,临时对象难道放在main函数栈中?
多谢!!
[解决办法]语句1既然是错误的,C++标准称之为“未定义行为”,发生啥结果都是正常的。
不要浪费时间在讨论错误的东西有啥“正确”的结果。
[解决办法]++
[解决办法]第一个函数,是返回函数栈中的数据,返回瞬间可以该数据仍然有效,但不保证
第二个函数,编译器会将函数栈中的返回值数据拷贝到返回栈中
[解决办法]数据在栈中可能没有立即擦除内存地址而已!
导致可以拿到有效数据的
[解决办法]你前面的对char的可控 没触犯未定义行为
用这个char 说明不了存在可控的未定义行为
另外不管实现为 有符号 还是无符号
根据你做出的保证 可以保证使用char没有风险
[解决办法]编译器可以优化掉一些无关紧要的拷贝构造
gcc直接优化掉了
典型的例子就是
string s = "aaaa";理论上是先执行一次带参数构造,再执行一次拷贝.但实际上就执行一次构造