c++ - 为什么 GetLastError() 会根据调用方式返回 0 或 2?

标签 c++ c winapi exception mingw

我正在使用 mingw g++ 4.6.1 和 -O0,WinXP SP2。

Minimal working example is here.

g++ 配置了 --disable-sjlj-exceptions --with-dwarf2。

GetLastError() 根据抛出异常的方式返回 0 或 2:

throw runtime_error(error_message());

伪造的“错误代码:0”被打印出来,并且

const string msg = error_message();

throw runtime_error(msg);

按预期打印“错误代码:2”。

首先,我认为 GetLastError() 被调用了两次,但调试显示它只被调用了一次,正如预期的那样。

这是怎么回事?

最佳答案

设置throw 的代码可能会在某处调用自身内部的 Win32 API 函数,将 Last-Error 值重置为 0。这可能发生在之前 您对 error_message() 的调用。

调用 GetLastError() 不会自动将 Last-Error 值重置为 0,因此调用两次是安全的。

您的编译器/运行时是否生成调用 Win32 API 函数的代码将取决于您的特定运行时。为了安全且不依赖于此,请使用双语句版本:

const string msg = error_message();
throw runtime_error(msg);

更好的是,对于您代码的 future 读者来说,在 error_message() 之外调用 GetLastError() 会很有用:

const string msg = error_message(GetLastError());
throw runtime_error(msg);

这样,读者将在相应的 Win32 API 调用之后立即看到 GetLastError() 调用,这是它所属的位置。

关于c++ - 为什么 GetLastError() 会根据调用方式返回 0 或 2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8671483/

相关文章:

c++ - CreateWindowEx 发布 WM_SIZE?

winapi - 在 WM_PAINT 上重用先前的后台缓冲区

c++ - 我如何获得顺序线程ID

c++ - Visual Studio 2010 和 SSE 4.2

c++ - 在函数中打印全局变量而不是::运算符的任何替代方法

c - GCC 内联汇编 : "g" constraint and parameter size

c - return counter==0 产生一个 bool 值或整数?

c++ - 在 linux 中使用 C++ 强制删除文件

c# - 如何通过引用修改该字符串的非托管 C 库来发送字符串?

c++ - 从 C++ 中的另一个 .exe 生成用户自定义的 .exe