Предупреждение C26426
Глобальный инициализатор вызывает функцию без контекспра "символ" (i.22)
C++ Core Guidelines
I.22. Избегайте сложной инициализации глобальных объектов
Порядок выполнения инициализаторов для глобальных объектов может быть несогласованным или неопределенным, что может привести к проблемам, которые трудно воспроизвести и исследовать. Чтобы избежать таких проблем, глобальные инициализаторы не должны зависеть от внешнего кода, выполняемого во время выполнения, и которые могут зависеть от данных, которые еще не инициализированы. Это правило помечает случаи, когда глобальные объекты вызывают функции для получения их начальных значений.
Замечания
Правило игнорирует вызовы функций или встроенных функций при предположении, что эти вызовы
constexpr
будут вычисляться во время компиляции или гарантировать прогнозируемую выполнение во время выполнения.Вызовы встроенных функций по-прежнему помечены, так как средство проверки не пытается проанализировать их реализацию.
Это правило может быть шумным во многих распространенных сценариях, когда переменная определяемого пользователем типа (или стандартного контейнера) инициализирована глобально. Это часто связано с вызовами конструкторов и деструкторов. Он по-прежнему является допустимым предупреждением, так как он указывает на места, где может существовать непредсказуемое поведение или где будущие изменения во внешнем коде могут привести к нестабильности.
Статические члены класса считаются глобальными, поэтому их инициализаторы также проверяются.
Имя анализа кода: NO_GLOBAL_INIT_CALLS
Примеры
Проверка внешней версии:
// api.cpp
int api_version = API_DEFAULT_VERSION; // Assume it can change at run time, hence non-const.
int get_api_version() noexcept {
return api_version;
}
// client.cpp
int get_api_version() noexcept;
bool is_legacy_mode = get_api_version() <= API_LEGACY_VERSION; // C26426, also stale value
Проверка внешней версии была более надежной:
// api.cpp
int& api_version() noexcept {
static auto value = API_DEFAULT_VERSION;
return value;
}
int get_api_version() noexcept {
return api_version();
}
// client.cpp
int get_api_version() noexcept;
bool is_legacy_mode() noexcept {
return get_api_version() <= API_LEGACY_VERSION;
}