My program is written in C for Linux, and has many functions with different patterns for return values:
1) one or two return n on success and -1 on failure.
2) some return 0 on success and -1 on failure.
3) some return 1 on success and 0 on failure (I generally spurn using a boolean type).
4) pointers return 0 on failure (I generally spurn using NULL).
My confusion arises over the first three — functions that return pointers always return 0 on failure, that’s easy.
The first option usually involves functions which return a length which may only be positive.
The second option, is usually involved with command line processing functions, but I’m unsure it has correctness, perhaps better values would be EXIT_SUCCESS and EXIT_FAILURE?
The third option is intended for functions which are convenient and natural to be called within conditions, and I usually emulate a boolean type here, by using int values 1 and 0.
Despite this all seeming reasonably sensible, I still find areas where this is not so clear or obvious as to which style to use when I create the function, or which style is in use when I wish to use it.
So how can I add clarity to my approach when deciding upon return types here?
Pick one pattern per return type and stick with it, or you’ll drive yourself crazy. Model your pattern on the conventions that have long been established for the platform:
If you are making lots of system calls, than any integer-returning function should return
-1on failure.If you are not making system calls, you are free to follow the convention of the C control structures that nonzero means success and zero means failure. (I don’t know why you dislike
bool.)If a function returns a pointer, failure should be indicated by returning
NULL.If a function returns a floating-point number, failure should be indicated by returning a NaN.
If a function returns a full range of signed and unsigned integers, you probably should not be coding success or failure in the return value.
Testing of return values is a bane to C programmers. If failure is rare and you can write a central handler, consider using an exception macro package that can indicate failures using
longjmp.