Condividi tramite


Avviso C26426

L'inizializzatore globale chiama una funzione non constexpr 'symbol' (i.22)

Linee guida di base di C++

I.22: Evitare l'inizializzazione complessa di oggetti globali

L'ordine di esecuzione degli inizializzatori per gli oggetti globali può essere incoerente o indefinito, che può causare problemi difficili da riprodurre e analizzare. Per evitare questi problemi, gli inizializzatori globali non devono dipendere da codice esterno eseguito in fase di esecuzione e che può dipendere da dati non ancora inizializzati. Questa regola contrassegna i casi in cui gli oggetti globali chiamano funzioni per ottenere i valori iniziali.

Osservazioni:

  • La regola ignora le chiamate a constexpr funzioni o funzioni intrinseche sul presupposto che queste chiamate verranno calcolate in fase di compilazione o garantiscono un'esecuzione prevedibile in fase di esecuzione.

  • Le chiamate alle funzioni inline vengono ancora contrassegnate, poiché il controllo non tenta di analizzare l'implementazione.

  • Questa regola può essere rumorosa in molti scenari comuni in cui una variabile di un tipo definito dall'utente (o un contenitore standard) viene inizializzata a livello globale. Spesso è dovuto a chiamate a costruttori e distruttori. È comunque un avviso valido, poiché punta a luoghi in cui può esistere un comportamento imprevedibile o in cui le future modifiche nel codice esterno possono introdurre instabilità.

  • I membri di classe statici sono considerati globali, quindi vengono controllati anche i relativi inizializzatori.

Nome dell'analisi del codice: NO_GLOBAL_INIT_CALLS

Esempi

Controllo della versione esterna:

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

Controllo della versione esterna reso più affidabile:

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