Search code examples
c++creturn-valueconventionscorrectness

Standard C functions: Check for -1 or 0?


Many standard C and POSIX functions return -1 for error, and 0 on success, for example truncate, fflush, msync, etc.

int ret = truncate("/some/file", 42);

Is it better practice to check for success with ret != -1 or ret == 0, and why?

My Thoughts

It's my experience most people check for the error case (ret != -1), as there is typically only one (consider functions that return NULL or EOF on error). However in hindsight, one could see these functions could benefit from returning errno directly (where 0 is considered no error).

There is also the worry that a function returns something other than 0 or -1, or that additional return values are later added. In these scenarios, it makes sense to test for the "tightest" range of values indicating success (ret == 0).

Update0

It's an assumption of mine that people are aware that EOF is typically defined as -1.


Solution

  • In my opinion, it really depends on what you need to do and the range of return values.

    Take a call with one success value and many failure values. It's generally easier to == or != against the successful return value than check against any failure values. In this case, you would test against != success if you need to, say, log and return or throw in case of a failure.

    In a call with one and one, the desired behavior is more important, so I suggest choosing the more readable. If your codes needs to react to and possibly return on failure, then check for == failure instead of != success. The former is more readable, since it takes one step of thinking and the failure constant may be helpfully named.

    You may also want to consider which is more likely and handle that first, or which is numerically greater or lesser.

    In your case, with two functions sharing a success code and with differing failure codes, it falls to whichever seems more readable. I would agree that testing for == 0 in both cases would seem better, but it really depends on how much code comes between the calls. If you have a few dozen lines, there might not be much of a difference in readability. If it's very close, you might even be able to OR the results together and save yourself a few more steps.