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


Предупреждение C26427

Глобальный инициализатор обращается к объекту extern 'symbol' (i.22)

Основные рекомендации по C++: I.22. Избегайте сложной инициализации глобальных объектов

Глобальные объекты могут быть инициализированы в несогласованном или неопределенном порядке, что означает, что взаимозависимость между ними рискованно и следует избежать. Это руководство применимо, если инициализаторы ссылаются на другой объект, который считается extern.

Замечания

Объект считается, extern если он соответствует следующим правилам:

  • это глобальная переменная, extern помеченная описательом или статическим членом класса;
  • он не находится в анонимном пространстве имен;
  • он не помечен как const;
  • Статические члены класса считаются глобальными, поэтому их инициализаторы также проверяются.

Имя анализа кода: NO_GLOBAL_INIT_EXTERNS

Пример

Проверка внешней версии:

// api.cpp
int api_version = API_DEFAULT_VERSION; // Assume it can change at run time, hence non-const.

// client.cpp
extern int api_version;
bool is_legacy_mode = api_version <= API_LEGACY_VERSION; // C26427, also stale value

Проверка внешней версии была более надежной:

// api.cpp
int api_version = API_DEFAULT_VERSION; // Assume it can change at run time, hence non-const.

// client.cpp
extern int api_version;
bool is_legacy_mode() noexcept
{
    return api_version <= API_LEGACY_VERSION;
}