Is C++ compiler obligated to generate ‘ret’ instruction for a function without ‘return’ statement?

Recently I encountered a problem that a thread in my programe was somehow stopped (GDB indicates thread’s state as STOPPED). I have spent a couple of days debugging. This problem happended after I changed the version of the compiler some days ago. Finally I found out that the problem happens because a function is defined with int return type but does not have a return statement. So the asm code of the function does not have a ret instruction. When it reaches the end of the funcion in runtime, since no ret instruction exists, execution continues on the next instruction which is in another funciton. This causes the thread being stopped. I have checked the asm code generated by the compiler of previous version, and the same function does have a ret instruction.

In my experience, missing return statement in a function with non-void return type is not suggested, but should not results in thead stop. I want to know if I am wrong, or the compiler is wrong.

My question is, for a normally ended (not ended by exception, call, jmp…) function with non-void return type, is the compiler obligated to generate a ret instruction or not. Does it have any C++ standards or C++ specifications illustrating the compiler behavoir in this case?

I have done some search and found an answer for c# in this. How about for C++?

Answer

No.

For any non-void function except main, if there is any path through the function that does not return, your program exhibits undefined behaviour if that path is taken at runtime. Then the compiler is allowed to do whatever it feels like. Generally this results in just a missing ret statement but I have seen much weirder effects.

The standard specifies this in [stmt.return].2:

[..] Flowing off the end of a constructor, a destructor, or a
non-coroutine function with a cv void return type is equivalent to a
return with no operand. Otherwise, flowing off the end of a function
other than main (6.9.3.1) or a coroutine (9.5.4) results in undefined
behavior
.

(emphasis added)