this is a CeeLanguage pattern that returns a value indicating an error, and returns the actual error information out of band through a global or thread-local variable, typically called errno. some have a global function which can retrieve the last error. this pattern is common in unix system calls. the ACE framework adheres to this convention strictly. so for example, the error handling idiom looks like: int r = api_func(&result,x,y); if ( r==-1 ) { // handle error fprintf(stderr,"error %d doing api_func: %s\n", errno, strerror(errno)); exit(1); } for other API's like WinSock, they have a global function like GetLastError() instead of a global like errno. In the ComponentObjectModel, there is a per-thread global error object that can be queried for additional error information when a failed HRESULT is returned. Not all COM objects supply error information. ''Isn't it more often like?:'' if (! r=api_func(&result,x,y)) {// handle error... ---- In multithreaded C applications, each thread gets its own copy of errno; this is implemented in one of two ways: * using ThreadLocalStorage/ThreadLocalVariable * defined as a macro as follows: #define errno (*(__errno_func())) where __errno_func (which may be called something else) is a function which returns a pointer to the thread's copy of errno (determined in whatever fashion). This form is necessary for the result of the errno macro to be an EllValue; as errno must be assignable. Many think that errno should be ConsideredHarmful because: * It is easily ignored; code must be written to explicitly checked for errno != 0; it is easy to say IwillWriteThatLater and never do so. ** ''Forcing one to make a try/catch block is also dumb in my opinion. Some want to try to make a language be a spanking mechanism.'' * Signifying exceptional conditions via a set of integers is non-ideal (a registry of such values must be kept, and they cannot contain any context info; ExceptionObject''''''s are better at this). * Only one errno can be active at a time; if a second error occurs it clobbers the first. * Since it's a global variable (per-thread in multi-threaded apps), it suffers from all the sins attendent thereto. GlobalVariablesConsideredHarmful. ------ '''Alternatives''' to the same idea include: (result, errNo) = apiFunc(a,b,c); // python-like multi-return style if (errNo) {...} // Or: resAry = apiFunc(a,b,c); // assoc. array or object with result & err info if (resAry.err) { print("Oopsie: " & resAry.errMessage); // more than just integer info } else { useValue(resAry.value); }