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?
A function that returns a value is called a value-returning function. A function is value-returning if the return type is anything other than void . A value-returning function must return a value of that type (using a return statement), otherwise undefined behavior will result.
What should main() return in C and C++? The return value for main is used to indicate how the program exited. If the program execution was normal, a 0 return value is used. Abnormal termination(errors, invalid inputs, segmentation faults, etc.) is usually terminated by a non-zero return.
A return statement ends the execution of a function, and returns control to the calling function. Execution resumes in the calling function at the point immediately following the call. A return statement can return a value to the calling function.
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 -1
on 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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With