Thinking back decades to when I took my first "C" class, I seem to remember that in the absence of a return statement in a function, the value of the last expression on the stack was returned. In that case, yes, it would be guaranteed behavior.
However, this is fuzzy in my memory, and putting in a return statement is so much better in so many ways, so I never do it without the return statement. I can't be 100% certain that I have my facts straight on this one--but yes, I think the @OP is correct.
But why? Put in the return statement and make it clear what the code is trying to do. Six keystrokes aren't worth the potential headache.
Just for completeness sake...
ISO/IEC 9899 is the C standard, as far as I know.
ISO/IEC 9899:TC3 draft section 188.8.131.52, "The return statement", item #12 states,
If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
So there you go. If your foo function reaches }, and you try to use its result, the behavior is undefined. And I'm sure the C++ standard says something along the same lines.
A particular compiler might guarantee behavior that goes beyond that standard, as an extension, but it's still undefined behavior per the standard. But C existed before the ISO standard, and I don't know how things like that worked before standardization. It could be that compilers guaranteed a particular behavior. But in modern C/C++, you certainly cannot assume this.
The difference is:
in C, the undefined behaviour is only if the caller tries to use the result;
in C++, it is undefined behaviour even if the caller ignores the result. https://eel.is/c++draft/stmt.return#4
This difference is understandable; in C++, the return type may be one with a non-trivial destructor.