我是C ++编程的新手,但这个问题一直在我的脑海里旋转。我知道在函数中返回对局部变量的引用是非法的,即编译此代码片段:
awk 'NR==1 {p=match($0,"Name")}
length($0)>p {last=substr($0,p)}
END {print last}' file
Micro Pratique N°247 Avril 2017.pdf
导致编译器发出警告,然后发生运行时错误。但是,为什么这段代码在没有任何警告的情况下编译而且运行没有错误?
inline int& funref() {
int a = 8;
return a; // not OK!
}
我的编译器是Linux Fedora平台上的g ++。
答案 0 :(得分:5)
它仍然是错的,它恰好是通过(非)快乐的巧合来工作。
此代码具有未定义的行为以及所有常见的警告(它可能始终有效,它可能始终有效,直到修复得太晚,它可能会引发你的房子并与你的未婚妻一起逃跑)。 / p>
编译器不需要为每个可能的错误发出诊断(警告或错误消息),因为它始终不可能这样做。在这里,至少你当前版本的g ++没有发出警告。不同的编译器,或不同版本的g ++,甚至是带有不同标志的相同版本,可能会警告您。
答案 1 :(得分:-3)
您无法返回对局部变量的引用的原因是因为当函数返回时局部变量将被擦除。简而言之,编译器会阻止您引用垃圾数据。
但是,编译器不具有防弹功能(如示例#2所示)。
但它确实可以用于检索单例实例。
inline int& funref()
{
static int* p_a = nullptr;
if (nullptr == p_a)
p_a = new int(8);
return *p_a;
}
这种情况有效,因为p_a指向的内存在函数返回后仍然有效。