The following code compiles successfully in g++ version 10.1.0:
int main()
{
int& x = x;
return x;
}
The compiler even has a warning defined for this, suggesting it's intentional that it isn't an error. When compiled with -Wall, it returns the following output:
<stdin>: In function ‘int main()’:
<stdin>:3:14: warning: reference ‘x’ is initialized with itself [-Winit-self]
3 | int& x = x;
| ^
<stdin>:3:14: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]
3 | int& x = x;
|
My testing has shown that this results in a reference to a value at address 0, same as if it were declared as the int& x = *(int*)nullptr;. Naturally, this results in a segfault if the value referenced by x is ever used.
I can think of one (questionable) case where this might be useful: if you want to call a method on a class with no accessible constructor, when that method isn't static but nonetheless doesn't make any use of the class's data:
struct S {
S() = delete;
int value() { return 69; }
};
int main()
{
S& s = s;
return s.value();
}
But then there are other ways to do that, which don't even give warnings with -Wall and are less likely to be undefined behavior. (For example, ((S*)0)->value().)
So what I'm asking is: is this in fact undefined behavior? It certainly seems like something that would be. Is there any conceivable situation in which a self-reference is the best solution? And if not, why is the warning suppressed by default?