Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
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
constexprbelső 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;
}