编译器警告 C5248
节“section-name”是为 C++ 动态初始化保留的。 手动放入节中的变量可能已优化,并且其相对于编译器生成的动态初始值设定项的顺序未指定
备注
Microsoft C++ 编译器使用保留节名称实现 C++ 动态初始化等功能的内部实现。 如果代码在保留节中插入变量,例如 .CRT$XCU
,它会干扰编译器。 变量不被视为 C++ 动态初始值设定项。 此外,未指定与编译器生成的动态初始值设定项相比的相对初始化顺序。
若要解决此错误,请不要创建使用保留名称的节或在保留节中插入变量。
使用编译器生成的动态初始值设定项的特定相对顺序,没有 C++ 标准符合标准,可以跨转换单元初始化变量。 在编译器生成的 C++ 动态初始值设定项之前或之后强制初始化的方法特定于实现。 有关特定于 Microsoft 实现的详细信息,请参阅 CRT 初始化。
编译器警告 C5248 是 Visual Studio 2019 版本 16.11 中的新增功能。 此功能默认处于关闭状态。 有关如何启用此警告的详细信息,请参阅默认情况下关闭的编译器警告。
示例
尝试模拟动态初始化的 C++ 编译器行为的代码通常采用以下形式:
void f();
typedef void (*type)();
#pragma section(".CRT$XCU", read)
__declspec(allocate(".CRT$XCU")) type i = f;
此代码使用保留名称 .CRT$XCU
创建节。 它阻止编译器使用预期属性创建节,并且可能会跳过其他初始化。 放置在节中的变量 i
是一个常规变量,不被视为编译器的初始值设定项。 编译器可能会优化掉 i
。 与其他动态初始值设定项相比,调用 f
时相对顺序未指定。
如果初始化顺序不重要,则可以使用此模式在启动时动态初始化变量:
void f();
struct init_helper {
init_helper() { f(); }
};
init_helper i;