13

Possible Duplicate:
Error handling in C code

Let's say you have a function:

int MightWork(){
  // if it works
  return x;

  // if it fails
  return y;

}

what should x and y be?

because I have another function:

if (MightWork){
  // do stuff #1
}else{
  // do stuff #2
}

I know for this particular example, using a return value of 1 will take the second code block to "do stuff # 1" and using a return value of 0 will take the second code block to "do stuff #2"

My question is what is preferred style in C to do this? Does a return value of 0 for a function indicate success and any other value indicates failure? Or vice versa? Or values under 0?

I'd like to make sure I'm writing my C code with the current style. Thanks!

Community
  • 1
  • 1
oxuser
  • 1,257
  • 2
  • 16
  • 23

8 Answers8

22

For non-pointer success/fail:

  • 0 => success
  • -1 => fail

For pointer functions:

  • NULL => fail
  • everything else => success
moshbear
  • 3,282
  • 1
  • 19
  • 33
  • Have you used -1 as a way to detect errors in multiple calls in a compact manner? E.g. `err += func1(); err += func2(); if (err<0) printf("error");` – Brian Sep 15 '17 at 00:03
  • So if success is return value 0, then would these be equivalent statements: " if( my_function() )" and "if( my_function() == 0)"? – Paradox Oct 06 '17 at 01:01
  • 1
    No, is success is marked by `0`, equivalent calls would be `if(!my_function())` and `if(my_function() == 0)`. – graywolf Oct 12 '19 at 13:54
4

Both are used, and it generally depends on if multiple error codes can be returned.

If your function will only "succeed" or "fail" with no additional information, I would recommend you return 0 for failure and 1 for success, because it's simpler and more semantically valid.

If your function may fail with multiple status codes, the only way to go is have 0 for success and other values for failure representing different statuses.

Ry-
  • 218,210
  • 55
  • 464
  • 476
2

Historically, a return value of 0 usually indicates success, while a return value of -1 indicates failure. You can also use more output values to give the user of the function more detailed information about the return state. It's another tradition to set a global error code variable, see e.g. GetLastError and SetLastError on Windows.

Jin Kwon
  • 20,295
  • 14
  • 115
  • 184
kol
  • 27,881
  • 12
  • 83
  • 120
2

In a conditional context, integers evaluate to "true" if they're non-zero and "false" if zero, so you should return 0 on failure if you want to use the function in that way, and make sure not to return 0 in the successful branch.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
2

There's no one right answer.

If your function is named/documented as evaluation of a predicate of some sort, then it should return a nonzero value (1 if convenient) for "true" and 0 for false.

If your function returns a pointer, 0 (null pointer) is just about the only reasonable way to report failure. Conventions like returning (void *)-1, MAP_FAILED, SEM_FAILED, and such are hideous and should not be copied. If you need to report a reason for failure, add an extra int *errorcode argument and include if (errorcode) *errorcode = reason; at the end of your function to allow callers that don't care about the reason to pass a null pointer.

If your function returns a numeric value such that only certain range values make sense (for instance only non-negative integers, or only finite floating point values) then use out-of-range values for error codes (e.g. negative integers or NaN/infinity) as error codes. If you don't have enough possible codes (for example only NaN) then use the int *errorcode approach described above.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
0

1 = true 0 = false

in general....

sometimes people use -1 for "error"

another way to handle this is with enums and sometimes #defines. Though many times people don't use this unless there is many errors.... and usually multiple errors are handled by various negative numbers.

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
0

In my opinion both could work , but in different case.

  1. If you make the function to do some operation , return 0 for success , -1 for failed, and set errno to appropriate value so that the caller could check it to know the detail of failure. Sometimes people also use different return values to mean different failures.

  2. If you would like the function to test some condition , you should make it return either TRUE or FALSE, and use if (XXX() == TRUE) later . The form of if (XXX()) is not recommended, though many people do that to save times of typing keyboard . TRUE and FALSE is not a built in data type in C , however many programming environments will define it as TRUE = 1 and FALSE = 0, you can do it yourself if you are not working in such an environment.

T.Rob
  • 31,522
  • 9
  • 59
  • 103
-4

use #define.

#define TRUE 1
#define FALSE 0

this helps any other person to understand your choice of standard for true and false value. Also, if the program code gets bigger, keeping track of the constants become difficult and might confuse. Using #define for constants is always a good practice.