It's not really defined and there are different approaches depending on the library and/or function you're using. In general, there's no way to differentiate between 0 and NULL (in fact, NULL is usually just a preprocessor macro expanding to 0).
In general, the following possibilities are used, sometimes even matched within one library depending on the usage:
- If a pointer is returnd, a return value of
0 usually indicates some kind of error.
- Functions with status codes (or
main entry points) usually return 0 in case there hasn't been any error.
- There are functions returning
0 if something hasn't been successfull (i.e. they return a boolean value).
- Some stdlib string functions return an "absurd" value in case there has been an error (or nothing found). For example,
std::string::find() will return -1 if the sub string couldn't be found. This is however wrapped/hidden behind a constant named value (std::string::npos) to avoid throwing around "magic values".
Is there a perfect way? I don't think so, but it really depends on the specific use case. If you return a pointer, returning 0 in case of a mistake is just perfect. If you're returning status codes, I'd go with either macros (similar to windows API) or enums. Don't even worry about any specific values - only use the names.