コンパイラの警告 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 の初期化