1

I am updating from Visual Studio 2013 to Visual Studio 2015 and noticed this difference in behaviour.

#include <stdexcept>
#include <WinSock2.h>
#include <ws2tcpip.h>

int main()
{
    WORD version = MAKEWORD(2, 2);
    WSADATA wsaData;

    if (WSAStartup(version, &wsaData) != 0)
    {
        throw std::runtime_error("This one is not thrown");
    }

    WSASetLastError(1);

    if (WSAGetLastError() != 1)
    {
        throw std::runtime_error("This one neither");
    }

#if 1
    std::runtime_error test("an error");
#endif

    if (WSAGetLastError() != 1)
    {
        throw std::runtime_error("This is thrown when the above code path is enabled");
    }

    return 0;
}

When I enable the std::runtime_error code path the WSAGetLastError flags is reset. Disable it and the program returns 0 without any problems.

bofjas
  • 1,186
  • 7
  • 19
  • Where is your call to `WSAStartup`? Read the docs: https://msdn.microsoft.com/en-us/library/windows/desktop/ms742209%28v=vs.85%29.aspx – PaulMcKenzie Mar 07 '16 at 19:39
  • I removed all code that was not essential for reproducing the problem to make the source more stack overflow friendly. I originally had WSAStartup in the beginning and the behaviour was identical. – bofjas Mar 07 '16 at 20:04
  • Fixed it to avoid drawing focus away from the actual question – bofjas Mar 07 '16 at 20:13

2 Answers2

1

The documentation says:

If a function call's return value indicates that error or other relevant data was returned in the error code, WSAGetLastError should be called immediately. This is necessary because some functions may reset the last extended error code to 0 if they succeed, overwriting the extended error code returned by a previously failed function.

Clearly creating this error object results in a call to a function that resets the thread error code.

As it happens, WSAGetLastError is an alias for GetLastError and so it's hardly surprising that the Win32 thread error status is modified when you create an object.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I actually saw that paragraph but I assumed it was only other WSA methods that would reset the flag. It's a bit weird that simply constructing an exception would modify the global error flag and since it changed between VS versions I was wondering if it was a bug. But I guess it matches the behavior in the paragraph. Thanks. – bofjas Mar 07 '16 at 20:25
  • how do assume to know, what std::runtime_error() is doing or not doing? Potentially it is logging itself into some file and thus calls the WriteFile(). And why would you want to assume something like this? –  Apr 24 '16 at 20:08
  • @Excess who is that addressed to? – David Heffernan Apr 24 '16 at 20:16
0

I ran into something similar on upgrading to msvc2015... a series of N apparently uninterrupted calls to WSAGetLastError, with the last one returning a different value than the first N-1. It took stepping though assembly code to find a constructor with a call to "new" in it, which would probably sometimes end up requiring more memory, which would reset the system error code. Lesson: cache the value from WSAGetLastError if you need it at a later time.