为什么创建std :: runtime_error会重置WSAGetLastError?

时间:2016-03-07 19:28:57

标签: c++ visual-studio exception visual-studio-2015 winsock2

我正在从Visual Studio 2013更新到Visual Studio 2015,并注意到这种行为差异。

#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;
}

当我启用std :: runtime_error代码路径时,会重置WSAGetLastError标志。禁用它,程序返回0没有任何问题。

2 个答案:

答案 0 :(得分:1)

documentation说:

  

如果函数调用的返回值表明错误代码中返回了错误或其他相关数据,则应立即调用WSAGetLastError。这是必要的,因为如果成功,某些函数可能会将最后一个扩展错误代码重置为0,从而覆盖先前失败函数返回的扩展错误代码。

显然,创建此错误对象会导致调用重置线程错误代码的函数。

碰巧,WSAGetLastError is an alias for GetLastError因此在创建对象时修改Win32线程错误状态并不奇怪。

答案 1 :(得分:0)

我在升级到msvc2015时碰到了类似的东西......一系列N个明显不间断的WSAGetLastError调用,最后一个返回的值与第一个N-1不同。它通过汇编代码来寻找一个构造函数来调用&#34; new&#34;在其中,有时可能最终需要更多内存,这将重置系统错误代码。课程:如果稍后需要,请缓存WSAGetLastError中的值。