Share via


編譯器警告 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 初始化