Avertissement C26426
L’initialiseur global appelle une fonction non constexpr 'symbol' (i.22)
C++ Core Guidelines
I.22 : Éviter l’initialisation complexe d’objets globaux
L’ordre d’exécution des initialiseurs pour les objets globaux peut être incohérent ou non défini, ce qui peut entraîner des problèmes difficiles à reproduire et à examiner. Pour éviter de tels problèmes, les initialiseurs globaux ne doivent pas dépendre du code externe exécuté au moment de l’exécution, et cela peut dépendre des données qui ne sont pas encore initialisées. Cette règle signale les cas où les objets globaux appellent des fonctions pour obtenir leurs valeurs initiales.
Notes
La règle ignore les appels à
constexpr
des fonctions ou des fonctions intrinsèques en supposant que ces appels seront calculés au moment de la compilation ou garantissent l’exécution prévisible au moment de l’exécution.Les appels aux fonctions inline sont toujours marqués, car le vérificateur ne tente pas d’analyser leur implémentation.
Cette règle peut être bruyante dans de nombreux scénarios courants où une variable d’un type défini par l’utilisateur (ou un conteneur standard) est initialisée globalement. Il est souvent dû aux appels aux constructeurs et aux destructeurs. Il s’agit toujours d’un avertissement valide, car il pointe vers des endroits où le comportement imprévisible peut exister ou où les modifications futures dans le code externe peuvent introduire une instabilité.
Les membres de classe statique sont considérés comme globaux, de sorte que leurs initialiseurs sont également vérifiés.
Nom de l’analyse du code : NO_GLOBAL_INIT_CALLS
Exemples
Vérification de version externe :
// 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
La vérification de version externe a été plus fiable :
// 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;
}