我想到了C++中的一个奇怪作弊。通常,我无法将引用走私到范围之外,因为无法在包含范围中定义未初始化的引用。但是,我可以定义一个指向包含引用的类的指针,无法对其进行初始化,然后为它分配一些初始化为局部变量的动态内存的地址。即使该动态对象包含对本应超出范围的变量的引用,但指向的对象仍然具有具有相同值的有效引用!即使我告诉它是-pedantic
,g++也不会抱怨,所以我认为它是有效的。但是如何,为什么?
struct int_ref
{
int &x;
int_ref(int &i): x(i) {}
};
#include <iostream>
using namespace std;
int main(void)
{
int_ref *irp;
int i = 1;
int_ref a(i); // Creates an int_ref initialized to i
irp = &a; // irp is now a pointer to a reference!
// Prints 1
cout << "irp->x = " << irp->x << " (i = " << i << ")" << endl;
i = 2;
// Prints 2
cout << "irp->x = " << irp->x << " (i = " << i << ")" << endl;
int j = 3;
int_ref b(j);
irp = &b;
// Prints 3
cout << "irp->x = " << irp->x << " (i = " << i << ", j = " << j << ")" << endl;
i = 1;
// Still prints 3
cout << "irp->x = " << irp->x << " (i = " << i << ", j = " << j << ")" << endl;
{
int k = 4;
irp = new int_ref(k);
// k goes out of scope
}
int k = 1; // Doesn't affect the other k, of course
// Prints 4 ?!
cout << "irp->x = " << irp->x << " (i = " << i << ", j = " << j << ")" << endl;
}
编辑:实际上,这可能是(如答案中所建议的)未诊断的悬挂引用。如果我这样定义
int_ref
怎么办:struct int_ref
{
const int &x;
int_ref(const int &i): x(i) {}
};
const
引用不必引用左值,因此没有明确定义的悬挂对象。代码是否仍未定义? 最佳答案
仅仅因为您的编译器没有为您的程序发出诊断信息,并不意味着您的程序是好的,有效的和安全的。
最后一行调用“未定义行为”,因为您有一个悬挂的引用。不需要由编译器诊断,但是也不能使之正确。您可能会得到4
(只是碰巧仍然在内存中的那个位置),您可能会获得一些其他值,您可能会遇到分段错误,或者您的PC可能会爆炸。
请不要这样做。
术语注释:这里没有“引用指针”(不存在这样的东西),只有指向int_ref
的指针。