GetLastError(), errno, FormatMessageA() and strerror_s()?

Stéphane picture Stéphane · Nov 18, 2013 · Viewed 9.4k times · Source

I'm confused as to the exact relationship between GetLastError() and errno. Are they the same numerical values, or something completely different? How do I know which one I should check?

And if I want to convert an error code to a string for debugging, can I use FormatMessageA() interchangeably with strerror_s()?

Lastly, is it true that WSAGetLastError() always returns the same as GetLastError(), or could they both return different values?

Answer

Stuart picture Stuart · Nov 18, 2013

There is no relationship between GetLastError and errno.

GetLastError gets the last error that was set by a Windows API function (for the current thread), while errno contains the last error that was stored into it by a C runtime library function (also for the current thread).

Almost all WinAPI functions, that return errors to their callers, will indicate in some way when an error occurs, and then set the error for the caller to get by calling GetLastError. NOTE: Not all WinAPI functions return errors to their callers.

For example, the documentation for the WinAPI function CreateFile says:

If the function succeeds, the return value is an open handle to the specified file, device, named pipe, or mail slot. If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

The C runtime library functions that return errors to their callers, will indicate in some way when an error occurs and then store a value in errno. NOTE: Not all C runtime library functions return errors to their callers.

For example, the documentation for the C runtime library function sqrt says:

The sqrt function computes the nonnegative square root of its argument. A domain error occurs if its argument is negative.

The documentation on domain errors says:

On a domain error, the function returns an implementation-defined value; and the value EDOM is stored in errno.

The values returned by GetLastError are not the same as the values stored in errno, so I think that answers the question about using FormatMessage and strerror_s.

I don't know if WSAGetLastError always returns the same values as GetLastError (although I notice that the list of error codes returned by GetLastError does include the error codes that WSAGetLastError can return). See System Error Codes (9000-11999). If you look at the error codes starting at around 10000 you will see the WSAGetLastError error codes.

In any case, I personally would not rely on them returning the same values. Why would that be useful? Just follow the documentation and call WSAGetLastError for Winsock2 functions, and GetLastError for other WinAPI functions. NOTE: You can use FormatMessage on the error codes returned by either function.