Sdílet prostřednictvím


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