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