Undefined behaviour is essentially defined by not resulting in an easy diagnosable error. Read into https://en.cppreference.com/w/cpp/language/ub. An advanced compiler might be able to detect one, but is not required to.
This is the true problem of UB - it actually can do exactly what you want it to do. Until it doesn't, resulting in bugs that do not trigger at first, making them potentially hard to fix when they finally do.
What a compiler might do with your piece of code is this:
- The memory for
tmp
is reserved within the stack.
- The reference is created. Let's for simplicity act as if it was a regular pointer. Essentially, the address of that memory is used.
- The reference is returned.
- As the function is left, everything in the stack memory belonging to the function is deallocated. This means that those memory addresses are no longer reserved, and another process might reserve it instead.
- However: there is no need to spend any time doing anything with the content of the memory at that position. It still contains a ten in integer format.
- Your console print accesses the memory at the address. While it is not reserved, it still contains the value. As your variable
t
is declared as integer, it reads that part of the memory as one, and the ten is still there, everything working out fine.
As that part of the memory is not reserved after the return, something else might however reserve it and write in it, before the console print happens. If so, the output might be very well be something like -36234646346.
Now, in all of this, I assumed a lot of things about how the compiler works. This is not given. Your question
"If you were asked what would this piece of code do, would you say it prints just fine or a compiler error?"
does not have a definite answer. One can say that it might do what you want, but that is not a given.
A common joke is that, since a compiler is allowed to do anything if the code has undefined behaviour, it could also result in a swarm of demons coming out of your nose.
That is of course exaggerated, but the things is, undefined behaviour can do a lot of things you really don't expect.
For example: look at this: http://www.cpp.sh/32x7f. In there, a two-dimensional array is accessed out of bounds in a console output. What happens when you run it is that it keeps on iterating, printing out the iterator variable at over a hundred while the for loop should have stopped after three. I have no idea what happens there, the out-of-bounds access should not be able to mess with the loop, but apparently it does. (Note that the global variable in there is bad style, but unrelated to the behaviour.)
Important thing is: learn to recognize undefined behaviour, and never rely on it working in a certain way.