在这里的堆栈溢出(现在已经被那些幂函数清除)的扩展参数之后,出现了一个问题,即何时应该真正调用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;
}
很明显,“纯粹主义者”的方法总是有效的!然而,
c++
语言标准是否保证“正常”方法也能工作?(也就是说,可以确定GetLastError()
作为sprintf
的参数将是在测试SetConsoleWindowInfo()
的返回值之后执行的第一个代码吗?)注:请不要对代码的质量评价太苛刻!如我所说,这是对原来问题的改编。
编辑:一个更典型的情况(我经常在我的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>;
}
但同样,
GetLastError()
是唯一的非常量参数。 最佳答案
我将把这个问题分成两个独立的问题:
“普通代码”示例是否按预期工作?
是的,这个确切的代码将按预期工作。其他函数参数是内置类型,即使没有定义order函数参数的求值,它们都不能干扰GetLastError
调用。
“普通代码”示例是调用GetLastError
的正确方法吗?
它不是,即使运行此代码会产生预期的结果。其原因是使用GetLastError
作为函数参数对其他函数参数引入了隐式约束,即它们不能有最后更改错误的副作用。这使得代码更容易出错,也更难维护。
因此,经验法则是在调用其他函数或创建/销毁对象之前,将最后一个错误值存储在某个变量中。
关于c++ - 使用GetLastError()的真正正确方法(时间)是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57760080/