Warning C26426
Global initializer calls a non-constexpr function 'symbol' (i.22)
C++ Core Guidelines
I.22: Avoid complex initialization of global objects
The order of execution of initializers for global objects may be inconsistent or undefined, which can lead to issues that are hard to reproduce and investigate. To avoid such problems, global initializers shouldn't depend on external code that's executed at run time, and that may depend on data that's not yet initialized. This rule flags cases where global objects call functions to obtain their initial values.
Remarks
The rule ignores calls to
constexpr
functions or intrinsic functions on the assumption that these calls either will be calculated at compile time or guarantee predictable execution at run time.Calls to inline functions are still flagged, since the checker doesn't attempt to analyze their implementation.
This rule can be noisy in many common scenarios where a variable of a user-defined type (or a standard container) is initialized globally. It's often due to calls to constructors and destructors. It's still a valid warning, since it points to places where unpredictable behavior may exist or where future changes in external code may introduce instability.
Static class members are considered global, so their initializers are also checked.
Code analysis name: NO_GLOBAL_INIT_CALLS
Examples
External version check:
// 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
External version check made more reliable:
// 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;
}