22

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?

Stéphane
  • 19,459
  • 24
  • 95
  • 136
  • 3
    `GetLastError` and `FormatMessage` are for Win32 errors. `errno` and `strerror` are for C runtime errors. They are unrelated. Each function documents which error code it sets. – Raymond Chen Nov 18 '13 at 20:28
  • 2
    possible duplicate of [Is WSAGetLastError() just an alias for GetLastError()?](http://stackoverflow.com/questions/15586224/is-wsagetlasterror-just-an-alias-for-getlasterror) – Raymond Chen Nov 18 '13 at 20:29
  • @RaymondChen but a socket errors are not c-runtime. Anyway I successfully use `errno`related functions in my program. Does this means that on Windows the `perror()` and `strerror()` is different from one's Win32 API? It is really interesting question: I am porting right now a little application from a GNU/Linux, and it wouldn't be good if `strerror()` suddenly refused to print a network errors. – Hi-Angel Aug 12 '14 at 13:54
  • @Hi-Angel [The `FormatMessage` function can be used to obtain the message string for the returned error.](http://msdn.microsoft.com/en-us/library/windows/desktop/ms741580%28v=vs.85%29.aspx) – nodakai Sep 07 '14 at 15:42
  • @nodakai I know it, that wasn't what I meant. I was wondering if I could use errno to get at least an error of a sockets. But now I already know, that isn't. Tbh I have no idea why someone could use a `errno` at all in Windows. What kind of errors in principle could I got? In *nix I can got via `errno` almost everything, but Windows doesn't seem to use it at all. Although it is a standard. This is sad. – Hi-Angel Sep 07 '14 at 15:58
  • @Hi-Angel if you call a C function `fopen` in a way like this: `fopen("test.txt", "ABC")`, then [`EINVAL` might be set](http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html) to `errno`... (I haven't tested it by myself, sorry) – nodakai Sep 07 '14 at 16:26

1 Answers1

25

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.

Stuart
  • 1,428
  • 11
  • 20
  • I know that the original question didn't have Linux in mind but since C Runtime is common in both Windows and Linux and Win32 API obviously doesn't exist on Linux, would using errno be useful in that case? – ZoomIn Oct 21 '20 at 05:38
  • @ZoomIn I'm sorry, I don't understand. What do you mean by "would using errno be useful in that case". – Stuart Oct 22 '20 at 01:47
  • What I mean to ask is 'does errno replace GetLastError() on Linux'? – ZoomIn Oct 22 '20 at 03:57
  • @ZoomIn I don't understand what you mean by "replace", there are two sets of functions with two different ways of indicating errors. As I said in the answer to the original question, "if you call a winapi function, like CreateFile, you check GetLastError (assuming that the function call failed), while if you call a C Standard Library function, like sqrt, you check errno (again assuming that the call failed)". – Stuart Oct 22 '20 at 11:23
  • Sorry, what I mean is apparently there is no Win32 API on Linux, so we are left with C Standard Library functions for fetching the error. Seems like that is the only way to do it as an alternative. And I was just asking if there is anything else that can be used in Linux. – ZoomIn Oct 22 '20 at 11:52
  • @ZoomIn yes, on Linux and other UNIX-likes, `errno` is generally the API we use to get the last operating system error. – mtraceur Oct 18 '22 at 19:12