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