Поделиться через


Предупреждение компилятора 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;

См. также

Инициализация CRT