Upozornění C26426
Globální inicializátor volá funkci bez constexpr (symbol) (i.22).
C++ Core Guidelines
I.22: Vyhněte se komplexní inicializaci globálních objektů
Pořadí provádění inicializátorů pro globální objekty může být nekonzistentní nebo nedefinované, což může vést k problémům, které se obtížně reprodukují a prošetřují. Aby se těmto problémům zabránilo, globální inicializátory by neměly záviset na externím kódu, který se spouští za běhu a který může záviset na datech, která ještě nejsou inicializována. Toto pravidlo označuje případy, kdy globální objekty volají funkce pro získání počátečních hodnot.
Poznámky
Pravidlo ignoruje volání
constexpr
funkcí nebo vnitřních funkcí za předpokladu, že se tato volání budou počítat v době kompilace nebo zaručit předvídatelné spuštění za běhu.Volání vložených funkcí jsou stále označená příznakem, protože se kontrola nepokouší analyzovat jejich implementaci.
Toto pravidlo může být hlučné v mnoha běžných scénářích, kdy se globálně inicializuje proměnná uživatelem definovaného typu (nebo standardního kontejneru). Často je to způsobeno voláním konstruktorů a destruktorů. Je to stále platné upozornění, protože odkazuje na místa, kde může existovat nepředvídatelné chování nebo kde budoucí změny v externím kódu mohou způsobit nestabilitu.
Statické členy třídy jsou považovány za globální, takže jejich inicializátory jsou také kontrolovány.
Název analýzy kódu: NO_GLOBAL_INIT_CALLS
Příklady
Kontrola externí verze:
// 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
Kontrola externí verze byla spolehlivější:
// 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;
}