C26426 NO_GLOBAL_INIT_CALLS

"Global initializer calls a non-constexpr function."

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. This can lead to issues which are hard to reproduce and investigate. To avoid such problems global initializers should not depend on external code which is executed at runtime and can potentially depend on data which is not yet initialized. This rule flags cases where global objects use function calls to obtain their initial values.

Remarks

  • The rule ignores calls to constexpr functions or intrinsic functions on assumption that these either will be calculated at compile time or guarantee predictable execution at runtime.
    • Calls to inline functions are still flagged since the checker doesn’t attempt to analyze their implementation.
    • This rule can be quite noisy in many common scenarios where a variable of a user defined type (or standard container) is initialized globally: this is often due to calls to constructors and destructors. This is still a valid warning since it points to places where unpredictable behavior may exist or future changes in external code may introduce instability.
    • Static class members are considered global, so their initializers are also checked. ## Example external version check // api.cpp int api_version = API_DEFAULT_VERSION; // Assume it can change at runtime, 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

Example

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