Almost every function in my engine is of the form:
error = function_name (arg1, arg2, arg3...);
The return value is always an error number. However, if all the function needs to return is a positive integer, you can return that in the return value.
Almost every function call is followed by:
if (error < 0) { return (error); }
... or sometimes some other code or function call might be tried before or instead-of the return(error); portion.
Overall, the following is common (though some elements are not required in many cases).
error = value = function_name (arg1, arg2...); // skip "value =" portion if only error values are returned
if (error < 0) {
free_resources (arg1, arg2, arg3...);
return (error);
}
// continue on with valid positive value
The above approach has proved the most convenient for me over many applications and libraries, after trying all sorts of alternatives. One equally viable approach, and possibly better because it is more consistent, is to never return anything but error values from functions, and remove all values in arguments. I didn't do that, but now and then think that's a better approach (because absolutely uniform in layout).