编译器警告 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;

另请参阅

CRT 初始化