Ostrzeżenie kompilatora C5247
sekcja "section-name" jest zarezerwowana dla inicjowania dynamicznego języka C++. Ręczne tworzenie sekcji zakłóca inicjowanie dynamiczne języka C++ i może prowadzić do niezdefiniowanego zachowania
Uwagi
Kompilator języka Microsoft C++ używa nazw sekcji zarezerwowanych do wewnętrznej implementacji funkcji, takich jak inicjowanie dynamiczne języka C++. Jeśli kod tworzy sekcję o takiej samej nazwie jak sekcja zarezerwowana, na przykład .CRT$XCU
, zakłóca działanie kompilatora. Może to uniemożliwić inicjację dynamiczną i spowodować niezdefiniowane zachowanie.
Aby rozwiązać ten błąd, nie twórz sekcji używającej nazwy zarezerwowanej.
Nie ma standardu C++ zgodnego ze sposobem inicjowania zmiennych między jednostkami tłumaczenia w określonej kolejności względnej z wygenerowanymi dynamicznymi inicjatorami kompilatora. Sposoby wymuszania inicjowania przed lub po wygenerowaniu dynamicznych inicjatorów języka C++ przez kompilator są specyficzne dla implementacji. Aby uzyskać więcej informacji na temat szczegółów implementacji specyficznych dla firmy Microsoft, zobacz Inicjowanie CRT.
Ostrzeżenie kompilatora C5247 jest nowe w programie Visual Studio 2019 w wersji 16.11. Domyślnie jest wyłączona. Aby uzyskać więcej informacji na temat włączania tego ostrzeżenia, zobacz Ostrzeżenia kompilatora, które są domyślnie wyłączone.
Przykład
Kod, który próbuje emulować zachowanie kompilatora języka C++ na potrzeby inicjowania dynamicznego, często przyjmuje następującą formę:
void f();
typedef void (*type)();
#pragma section(".CRT$XCU", read)
__declspec(allocate(".CRT$XCU")) type i = f;
Ten kod tworzy sekcję przy użyciu nazwy .CRT$XCU
zarezerwowanej . Zatrzymuje kompilator tworzenia sekcji z oczekiwanymi właściwościami i może pominąć inne inicjacje. Zmienna i
umieszczona w sekcji jest zmienną regularną i nie jest uznawana za inicjatora przez kompilator. Kompilator może optymalizować i
. Kolejność względna wywoływana w f
porównaniu z innymi inicjatorami dynamicznymi jest nieokreślona.
Jeśli kolejność inicjowania nie jest ważna, możesz użyć tego wzorca, aby dynamicznie zainicjować zmienną podczas uruchamiania:
void f();
struct init_helper {
init_helper() { f(); }
};
init_helper i;