编译器警告 C5247

节“section-name”是为 C++ 动态初始化保留的。 手动创建节会干扰 C++ 动态初始化,并可能导致未定义的行为

备注

Microsoft C++ 编译器使用保留节名称实现 C++ 动态初始化等功能的内部实现。 如果代码创建与保留节同名的节,例如 .CRT$XCU,它会干扰编译器。 它可能会阻止其他动态初始化并导致未定义的行为。

若要解决此错误,请不要创建使用保留名称的节。

使用编译器生成的动态初始值设定项的特定相对顺序,没有 C++ 标准符合标准,可以跨转换单元初始化变量。 在编译器生成的 C++ 动态初始值设定项之前或之后强制初始化的方法特定于实现。 有关特定于 Microsoft 实现的详细信息,请参阅 CRT 初始化

编译器警告 C5247 是 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 初始化