編譯器警告 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;