The last two lines of WebJose's post nailed it, in my opinion.
There's a simple rule regarding a situation such as this, which goes like: Never return a reference/pointer to a local object within a function. In doing so, you're reading/writing to a memory location that is no longer yours. Why such undefined behaviour occurs is blatantly obvious. It's bad practice to violate this rule and should be avoided, for the sake of the programs stability.
Why such undefined behaviour occurs is blatantly obvious.
From my point of view it isn't undefined behavior, you asked it to print the value of a memory address and it did; the compiler has done nothing wrong and the system has done nothing wrong. :0)
I believe, CodeMonkey, that people here are calling "undefined behavior" the fact that the contents are unpredictable, specifically referring to the case when it changes from one call to printf() to another. That's what people are calling undefined here, if I understand correctly. The actual mechanism of how to produce the output is not in question.
Exactly. If the behavior was defined, the standard would say, for example, "if a pointer to a local object x of type T is returned, what's returned instead is new T(x)". Then the behavior would be deterministic, and the pointer would always point to an 8.
This isn't the case for obvious reasons.