"To return or not to return? Ah ... that's the rub!"
Now that more than one theatre-goer and playwrite is moaning and groaning ...
One common coding style is to have a routine that returns a value, say getNextChar that returns a char, also use special "char" values (read that "normally illegal values") to return non-character information such as EOF, ERROR.
In spite of our C heritage and the large number of routines in "standard libraries" that use this technique it has been suggested that routines clearly distinguish between returned status and returned results, i.e. Don't use abnormal return values to indicate that a value isn't really being returned.
Instead have the routine return a boolean (or HRESULT) that indicates whether or not the routine worked and if it needs to pass back a result the result is returned via an [out] parameter that holds a valid return value if-and-only-if the boolean indicates as such.
As an additional step, clearly think through how much error information you want to package into the return status and whether it might be better to have a "GetLastError()" function that carries the burden of indicating what went wrong and just let the original routine return Ok/NotOk as a status/completion code.