In practice, the value being returned is probably the last value in some machine register (e.g. the one used to compute c
). However, according to the standards, both the return value and results if the caller accesses/users the returned value are undefined.
As to why this sort of abusive/ugly code construct is allowed.... Firstly, in early versions of C
there was no void
keyword, and - if no return type was specified - return type for a function was int
. For functions that were actually intended to return nothing, the technique was to (implicitly or explicitly) define them as returning int
, not return any value, and have the caller make no attempt to access/use the return value.
Since compiler vendors had some freedom in how they handled this sort of thing, they didn't have to take any particular care in ensuring there was a valid return value, or ensuring that the return value was unused. In practice, it was largely fortuitous that - if the return value was accessed - it often happened to contain the value of the last operation in the function. Some programmers stumbled upon this behaviour of their code and - since code that was terse and cryptic was often viewed as some virtue at the time - made use of it.
Later on, even when the compile vendors in question tried to change the behaviour (e.g. to emit an error message and reject the code when a function "fell off the end"), they received bug reports from developers (some of whom were quite vocal) about their programs no longer working. Sad as it is, the compiler vendors caved to the pressure. Other compile vendors also caved to similar bug reports (of the form "gcc and compiler X does it this way - yours should too") because a number of those bug reports came from developers at large companies or government bodies who were paying customers for the compiler vendors. This is the reason that such things are diagnosed by most modern compilers (usually as an optional warning, disabled by default, such as gcc's -Wall
option) and give behaviour that the developers expected.
The history of C, and therefore C++, is littered with a number of obscure features like this, which result from programmers exploiting some obscure behaviour of their early compilers and lobbying to prevent the behaviour being disabled.
The best modern practice is to turn on compiler warnings, and not to exploit such features. However, there is still enough legacy code - and developers who don't want to update codebases for various reasons (e.g. having to provide a slew of documentation to convince regulators the code still works) to stop using such features - that the features remain supported by compilers.