While reading this explanation on lvalues and rvalues, these lines of code stuck out to me:
int& foo();
foo() = 42; // OK, foo() is an lvalue
int &foo();
declares a function called foo()
with return type int&
. If you call this function without providing a body then you are likely to get an undefined reference error.
In your second attempt you provided a function int foo()
. This has a different return type to the function declared by int& foo();
. So you have two declarations of the same foo
that don't match, which violates the One Definition Rule causing undefined behaviour (no diagnostic required).
For something that works, take out the local function declaration. They can lead to silent undefined behaviour as you have seen. Instead, only use function declarations outside of any function. Your program could look like:
int &foo()
{
static int i = 2;
return i;
}
int main()
{
++foo();
std::cout << foo() << '\n';
}