Предупреждение компилятора C5247
раздел "section-name" зарезервирован для динамической инициализации C++. Создание раздела вручную будет препятствовать динамической инициализации C++ и может привести к неопределенному поведению.
Замечания
Компилятор Microsoft C++ использует зарезервированные имена разделов для внутренней реализации таких функций, как динамическая инициализация C++. Если код создает раздел с тем же именем, что и зарезервированный раздел, например .CRT$XCU
, он вмешивается в компилятор. Это может предотвратить другую динамическую инициализацию и вызвать неопределенное поведение.
Чтобы устранить эту ошибку, не создайте раздел, использующий зарезервированное имя.
Нет стандартного способа инициализации переменных в единицах перевода в определенном относительном порядке с созданными динамическими инициализаторами компилятора. Способы принудительной инициализации до или после создания динамических инициализаторов C++ зависят от реализации. Дополнительные сведения о реализации для конкретной корпорации Майкрософт см. в статье О инициализации 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;