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

问题描述:

我正在从Visual Studio 2013更新到Visual Studio 2015,并注意到这种行为差异。为什么创建一个std :: runtime_error重置WSAGetLastError?

#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没有任何问题。

+0

你打给'WSAStartup'的地方在哪里?阅读文档:https://msdn.microsoft.com/en-us/library/windows/desktop/ms742209%28v=vs.85%29.aspx – PaulMcKenzie

+0

我删除了所有代码,这些代码不是重现问题所必需的源更多的堆栈溢出友好。我原本是在WSAStartup开始的,行为是一样的。 – bofjas

+0

修正它以避免将焦点从实际问题中删除 – bofjas

documentation说:

如果一个函数调用的返回值指示错误或其他相关数据的错误代码返回,WSAGetLastError应立即调用。这是必要的,因为如果一些函数成功,可能会将上次扩展错误代码重置为0,从而覆盖以前失败函数返回的扩展错误代码。

清楚地创建此错误对象会导致调用重置线程错误代码的函数。

碰巧,WSAGetLastError is an alias for GetLastError所以当你创建一个对象时,Win32线程错误状态被修改并不奇怪。

+0

我实际上看到了那段,但我认为这只是其他WSA方法会重置标志。有点奇怪,只是构造一个异常会修改全局错误标志,并且因为它在VS版本之间发生了变化,所以我想知道它是否是一个错误。但我想它符合段落中的行为。谢谢。 – bofjas

+0

怎么知道,std :: runtime_error()在做什么或不做什么?可能它将自己记录到某个文件中,因此调用WriteFile()。你为什么想要假设这样的事情? – 2016-04-24 20:08:13

+0

@超越那个给谁? –

我在升级到msvc2015时遇到了类似的情况......一系列N明显不间断地调用WSAGetLastError,最后一个返回的值与第一个N-1不同。它通过汇编代码来寻找一个调用“new”的构造函数,这可能最终需要更多的内存,这会重置系统错误代码。课程:如果您稍后需要,请缓存来自WSAGetLastError的值。