Compartilhar via


Aviso C26426

O inicializador global chama uma função não-constexpr de 'símbolo' (i.22)

Diretrizes Principais do C++

I.22: Evitar inicialização complexa de objetos globais

A ordem de execução dos inicializadores para objetos globais pode ser inconsistente ou indefinida, o que pode levar a problemas difíceis de reproduzir e investigar. Para evitar esses problemas, os inicializadores globais não devem depender do código externo executado em tempo de execução e isso pode depender dos dados que ainda não foram inicializados. Essa regra sinaliza casos em que objetos globais chamam funções para obter seus valores iniciais.

Comentários

  • A regra ignora chamadas para constexpr funções ou funções intrínsecas na suposição de que essas chamadas serão calculadas em tempo de compilação ou garantirão a execução previsível em tempo de execução.

  • As chamadas para funções embutidas ainda são sinalizadas, já que o verificador não tenta analisar sua implementação.

  • Essa regra pode ser barulhenta em muitos cenários comuns em que uma variável de um tipo definido pelo usuário (ou um contêiner padrão) é inicializada globalmente. Muitas vezes é devido a chamadas para construtores e destruidores. Ainda é um aviso válido, pois aponta para lugares onde comportamentos imprevisíveis podem existir ou onde futuras alterações no código externo podem introduzir instabilidade.

  • Os membros da classe estática são considerados globais e, portanto, seus inicializadores também são verificados.

Nome da análise de código: NO_GLOBAL_INIT_CALLS

Exemplos

Verificação de versão externa:

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

Verificação de versão externa tornada mais confiável:

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