Ostrzeżenie kompilatora C5248
sekcja "section-name" jest zarezerwowana dla inicjowania dynamicznego języka C++. Zmienne ręcznie umieszczone w sekcji mogą być zoptymalizowane, a ich kolejność względem kompilatora wygenerowanych dynamicznych inicjatorów nie jest określona
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 wstawia zmienną w sekcji zarezerwowanej, na przykład .CRT$XCU
, zakłóca działanie kompilatora. Zmienna nie jest uznawana za inicjator dynamiczny języka C++. Ponadto jego względna kolejność inicjowania w porównaniu do kompilatora wygenerowanych dynamicznych inicjatorów nie jest określona.
Aby rozwiązać ten problem, nie należy tworzyć sekcji, która używa nazwy zarezerwowanej ani wstawiania zmiennej w sekcji 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 C5248 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;