Udostępnij przez


Ostrzeżenie C26427

Globalny inicjator uzyskuje dostęp do obiektu extern "symbol" (i.22)

Podstawowe wytyczne języka C++: I.22: Unikaj złożonego inicjowania obiektów globalnych

Obiekty globalne mogą być inicjowane w niespójnej lub niezdefiniowanej kolejności, co oznacza, że współzależność między nimi jest ryzykowna i należy unikać. Ta wskazówka ma zastosowanie, gdy inicjatory odwołują się do innego obiektu, który jest uważany za extern.

Uwagi

Obiekt jest uznawany za extern zgodny z następującymi regułami:

  • jest to zmienna globalna oznaczona specyfikatorem extern lub statyczna składowa klasy;
  • nie znajduje się w anonimowej przestrzeni nazw;
  • nie jest ona oznaczona jako const;
  • Statyczne składowe klasy są uznawane za globalne, więc ich inicjatory są również sprawdzane.

Nazwa analizy kodu: NO_GLOBAL_INIT_EXTERNS

Przykład

Sprawdzanie wersji zewnętrznej:

// 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

Sprawdzanie wersji zewnętrznej sprawiło, że stał się bardziej niezawodny:

// 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;
}