2016-03-07 45 views
1

我正在從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

回答

1

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

@超越那個給誰? –

0

我在升級到msvc2015時遇到了類似的情況......一系列N明顯不間斷地調用WSAGetLastError,最後一個返回的值與第一個N-1不同。它通過彙編代碼來尋找一個調用「new」的構造函數,這可能最終需要更多的內存,這會重置系統錯誤代碼。課程:如果您稍後需要,請緩存來自WSAGetLastError的值。

相關問題