Compartir vía


Advertencia C26426

El inicializador global llama a una función 'symbol' no constexpr (i.22)

C++ Core Guidelines

I.22: Evitar la inicialización compleja de objetos globales

El orden de ejecución de inicializadores para objetos globales puede ser incoherente o indefinido, lo que puede provocar problemas difíciles de reproducir e investigar. Para evitar estos problemas, los inicializadores globales no deben depender del código externo que se ejecuta en tiempo de ejecución y que puede depender de los datos que aún no se hayan inicializado. Esta regla marca los casos en los que los objetos globales llaman a funciones para obtener sus valores iniciales.

Comentarios

  • La regla omite las llamadas a constexpr funciones o funciones intrínsecas en la suposición de que estas llamadas se calcularán en tiempo de compilación o garantizarán una ejecución predecible en tiempo de ejecución.

  • Las llamadas a funciones insertadas siguen marcadas, ya que el comprobador no intenta analizar su implementación.

  • Esta regla puede ser ruidosa en muchos escenarios comunes en los que una variable de un tipo definido por el usuario (o un contenedor estándar) se inicializa globalmente. A menudo se debe a llamadas a constructores y destructores. Sigue siendo una advertencia válida, ya que apunta a lugares donde puede existir un comportamiento imprevisible o donde los cambios futuros en el código externo pueden introducir inestabilidad.

  • Los miembros de clase estática se consideran globales, por lo que también se comprueban sus inicializadores.

Nombre del análisis de código: NO_GLOBAL_INIT_CALLS

Ejemplos

Comprobación de versiones externas:

// 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 comprobación de versiones externa hizo más confiable:

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