I used to think returning a reference is bad as our returned reference will refer to some garbage value. But this code works (matrix
is a class):
co
I see no buf
declared anywhere, which means it doesn't go out of scope with function return, so it's okay. (it actually looks like it's meant to be matrixbuf
which is also fine, because it's static
).
EDIT: Thanks to R. Martinho Fernandes for the guess. Of course it is matrix buf
, so it makes buf
static array in which temporary is allocated to make sure it doesn't get freed when the function returns and therefore the return value is still valid.
This is safe up to a point, but very dangerous. The returned reference
can't dangle, but if client code keeps it around, at some future point,
the client is in for a big surprise, as his value suddenly changes to a
new return value. And if you call get_matrix_temp
more than
max_matrix_temp
times in a single expression, you're going to end up
overwriting data as well.
In the days before std::string
, in code using printf
, I used this
technique for returning conversions of user defined types, where a
"%s"
specifier was used, and the argument was a call to a formatting
function. Again, max_matrix_temp
was the weak point: a single
printf
which formatted more instances of my type would output wrong
data. It was a bad idea then, and it's a worse idea now.
buf
is declared as static
, meaning it retains it's value between calls to the function:
static matrix buf[max_matrix_temp];
i.e. it's not created on the stack as int i = 0;
would be (a non-static local variable), so returning a reference to it is perfectly safe.
This following code is dangerous, because the memory for the variable's value is on the stack, so when the function returns and we move back up the stack to the previous function, all of the memory reservations local to the function cease to exist:
int * GetAnInt()
{
int i = 0; // create i on the stack
return &i; // return a pointer to that memory address
}
Once we've returned, we have a pointer to a piece of memory on the stack, and with dumb luck it will hold the value we want because it's not been overwritten yet — but the reference is invalid as the memory is now free for use as and when space on the stack is required.