Megosztás:


C26426 figyelmeztetés

A globális inicializáló egy nem constexpr függvény "szimbólumát" hívja meg (i.22)

C++ alapvető irányelvek

I.22: A globális objektumok komplex inicializálásának elkerülése

A globális objektumok inicializálóinak végrehajtási sorrendje inkonzisztens vagy meghatározatlan lehet, ami nehezen reprodukálható és kivizsgálható problémákhoz vezethet. Az ilyen problémák elkerülése érdekében a globális inicializálók nem függhetnek a futtatáskor végrehajtott külső kódtól, és ez az inicializálódott adatoktól is függhet. Ez a szabály azokat az eseteket jelöli, amikor a globális objektumok függvényeket hívnak meg a kezdeti értékek lekéréséhez.

Megjegyzések

  • A szabály figyelmen kívül hagyja a függvények vagy constexpr belső függvények hívásait azzal a feltételezéssel, hogy ezek a hívások fordítási időben lesznek kiszámítva, vagy futásidőben kiszámítható végrehajtást garantálnak.

  • A beágyazott függvények hívásai továbbra is megjelölve vannak, mivel az ellenőrző nem próbálja elemezni a megvalósításukat.

  • Ez a szabály számos gyakori forgatókönyvben zajos lehet, amikor egy felhasználó által definiált típusú változó (vagy egy standard tároló) inicializálva van globálisan. Ennek oka gyakran a konstruktorok és a destruktorok hívása. Ez továbbra is érvényes figyelmeztetés, mivel olyan helyekre mutat, ahol a kiszámíthatatlan viselkedés létezhet, vagy ahol a külső kód jövőbeli változásai instabilitást eredményezhetnek.

  • A statikus osztálytagok globálisnak minősülnek, így az inicializálóikat is ellenőrzik.

Kódelemzés neve: NO_GLOBAL_INIT_CALLS.

Példák

Külső verzió ellenőrzése:

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

A külső verzió ellenőrzése megbízhatóbbá tette a következőt:

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