visual-c++ - 代码分析警告 (C26426) 和使用 RegisterWindowMessage - 如何解决?
问题描述
代码:
#define UWM_TEST _T("UWM_TEST_{GUID_VALUE_HERE}")
static const UINT UWM_TEST_MSG = ::RegisterWindowMessage(UWM_TEST);
以上工作正常,但代码分析抱怨:
C26426:全局初始化程序调用非 constexpr 函数
RegisterWindowMessageW
(i.22)。
前述规定:
全局对象的初始化程序的执行顺序可能不一致或未定义。这可能会导致难以重现和调查的问题。为避免此类问题,全局初始化程序不应依赖于在运行时执行的外部代码,并且可能依赖于尚未初始化的数据。此规则标记全局对象调用函数以获取其初始值的情况。
我已经查看了链接页面上的示例,但我不明白我必须做什么来纠正这个以进行代码分析。
还在这里记录了这个问题:https ://developercommunity.visualstudio.com/t/Global-initializer-calls-a-non-constexpr/1563190
解决方案
如果您的UWM_TEST_MSG
消息仅在特定类的成员函数中使用,那么您可以将其设为const
(但不是 static
)该类的成员,而不是将其定义为(静态)全局常量,如下所示:
class MyClass
{
private:
#define UWM_TEST _T("UWM_TEST_{GUID_VALUE_HERE}")
const uint32_t UWM_TEST_MSG = ::RegisterWindowMessage(UWM_TEST);
///...
};
否则(如果消息被更广泛地使用),您可以使其成为public
应用程序类的类似(但)成员:
class MyApp : public CWinApp
{
public:
#define UWM_TEST _T("UWM_TEST_{GUID_VALUE_HERE}")
const uint32_t UWM_TEST_MSG = ::RegisterWindowMessage(UWM_TEST);
///...
};
在后一种情况下,您需要将所有出现的标识符更改为类似于以下表达式的内容(当然,除非它在 的成员中使用MyApp
):
static_cast<MyApp*>(AfxGetApp())->UWM_TEST_MSG
(或者,如果你extern MyApp theApp;
的代码中有一个声明,就像 MFC 程序通常做的那样,你可以使用theApp.UWM_TEST_MSG
而不是上面的表达式。)
无论哪种方式,使消息成为类的非静态(但仍然const
)数据成员(无论是哪个),都将避免警告(以及它突出显示的潜在问题),因为RegisterWindowMessage
只有在对象时才会调用该类的实例化。