General rule: negative or positive values โ€‹โ€‹for the error code in C / C ++

I have my own type and return functions defined as follows:

typedef enum xx_return_t { success = 0, general_error = -1, specific_error = -2, [...] } xx_return_type; xx_return_type generalFunction(void) { if(there_was_an_error) return general_error; } 

However, I'm a little unsure of the error type values โ€‹โ€‹here; What is the standard / best practice for error values โ€‹โ€‹in C / C ++ - negative or positive?

Update: Thanks for the reply! I searched for information in both C and C ++, but I also understand that this creates good questions on the general structure and methods specific to each language (exceptions, error codes, returning objects, etc.).

+8
c ++ c
source share
5 answers

These are really two completely different questions (versions in C and C ++) disguised as it.

In C ++, the answer is simple: use return values โ€‹โ€‹for ... return data values โ€‹โ€‹and use exceptions for cases of errors / exceptions. Do not use return values โ€‹โ€‹to check for errors in pure C ++ (the C API library for C ++ is a different story).

In C, you do not have this option, so I would suggest using 0 for success and negative numbers for error codes. This leaves flexibility if you want to use positive numbers for additional success information (e.g. read calls)

+15
source share

C ++:

  • This is a matter of choice, I have seen both.
  • Use exceptions!
+4
source share

I do not know about C ...

... but in C ++ the idea is not to use error codes at all.

I do not mean that you should use exceptions, but the error code is not very informative (there is no context, what FILE_NOT_FOUND cost when the file name is unknown?).

In those cases where I did not use exceptions, I preferred objects with a complete error. An example would be:

 boost::variant<File, Error> open(std::string const& filename, FileMode mode); 

where you get either a file or an error, depending on what happens.

+2
source share

There are several conventions to choose from:

  • microsoft uses 0 = FALSE = error for most of its high-level api. and allows the user to search for a specific error with the global function GetLastError()
  • microsoft uses 0 = ok for lower level apis like registry, audio or telephony. they all return a type similar to HRESULT containing a specific error code.
  • The posix functions returning a status usually return -1 for an error, and allow the user to search for an error through the errno global variable
  • pointer return functions usually return NULL for error
  • C ++ STL functions return 'end' for a status of type 'not found'. errors like out-of-memory are flagged using an exception.

In general, it is more important that you use your agreement consistently than which agreement you use.

Btw, some examples of how not to do this can be found in microsoft header files:

 #define S_OK ((HRESULT)0x00000000L) #define S_FALSE ((HRESULT)0x00000001L) 

Also beware of two different error values โ€‹โ€‹for HANDLE in windows: 0 or INVALID_HANDLE_VALUE

+2
source share

It is better to use 0 (zero) and a nonzero value so that they can also be considered logical. Usually false is 0, and true is something else.

+1
source share

All Articles