使用GetLastError()的真正正确方法(时间)是什么?

Adr*_*ica 2 c++ winapi

在这里对Stack Overflow(现在已经被Powers-be-Be清除)进行了扩展讨论之后,出现了一个问题:何时应该真正调用该GetLastError函数。

注意:这不是关于样式的问题,而只是关于:(a)在“非纯粹”代码的情况下,标准保证(或不保证)什么?(b)就安全winapi编程而言,什么是“最佳实践”?

这是一个示例(改编自上面发布的原始问题):

#include <windows.h>
#include <stdio.h>
#include <iostream>

//#define PURIST 1

using namespace std;
int main()
{
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SMALL_RECT wSize = { 0,0,60,20 }; // Works on my screen!
    if (hConsole == nullptr) {
        cout << "Console Handle is Null" << endl;
        return 1;
    }
    else {
        char message[256];
        if (!SetConsoleWindowInfo(hConsole, TRUE, &wSize)) {
            #ifdef PURIST
            // 'Purist' code ...
            DWORD eCode = GetLastError();
            sprintf(message, "SetConsoleWindowInfo failed; code = %d!", eCode);
            #else
            // More normal code ...
            sprintf(message, "SetConsoleWindowInfo failed; code = %d!", GetLastError());
            #endif
        }
        else {
            strcpy(message, "SetConsoleWindowInfo call succeeded!");
        }
        cout << message << endl;
    }
    getchar(); // Just to stop console closing!
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

显然,“纯粹”方法将始终正常工作!但是,c++语言标准是否保证“正常”方法也将起作用?(也就是说,可以确定GetLastError()作为参数to sprintf将是测试返回值之后执行的第一个代码SetConsoleWindowInfo()

PS:请不要对我的代码质量太苛刻!正如我所说,这是对原始问题的改编。

编辑:一种更典型的情况(我在Windows应用程序中使用了很多)看起来像这样:

if (<WinApi call failed>) {
    TCHAR eText[256];
    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(), 0, eText, 255, nullptr);
    // Do something with eText, etc. ...
    return <error code>;
}
Run Code Online (Sandbox Code Playgroud)

但是,这GetLastError()也是唯一的非常量参数。

use*_*670 5

我将把这个问题分为两个独立的问题:

  1. “正常代码”示例是否按预期工作?
    是的,此确切的代码将按预期工作。其他函数自变量是内置类型,即使未定义顺序函数自变量的求值,它们也不会干扰GetLastError调用。
  2. “普通代码”示例是正确的调用方式GetLastError吗?
    即使运行此代码会产生预期的结果,事实并非如此。这样做的原因是,使用GetLastErroras函数参数对其他函数参数引入了隐式约束,即它们必须没有改变最终错误的副作用。这使得代码更容易出错,并且更难以维护。

因此,经验法则是在调用其他函数或创建/销毁对象之前,将最后的错误值存储在某个变量中。