Aviso C26439

Esse tipo de função pode não ser lançada. Declare-o "noexcept".

Diretrizes principais do C++ F.6: Se sua função não deve ser lançada, declare-a noexcept

Algumas operações nunca devem lançar exceções. Suas implementações devem ser confiáveis e devem lidar com possíveis condições de erros normalmente. Eles não devem usar exceções para indicar falha. Essa regra sinaliza casos em que essas operações não são explicitamente marcadas como noexcept, o que significa que elas podem lançar exceções e os consumidores não podem fazer suposições sobre sua confiabilidade.

É importante que essas funções sejam confiáveis, pois muitas vezes são usadas como blocos de construção para implementar funções com garantias de segurança de exceção. Um construtor de movimentação que lança forçará os contêineres STL (Standard Template Library) a retornar para operações de cópia, reduzindo o desempenho do tempo de execução.

Nome da análise de código: SPECIAL_NOEXCEPT

Comentários

  • Tipos especiais de operações:

    • destruidores;
    • operadores de construtores de movimento e de atribuição de movimento;
    • funções padrão com semântica de movimento: std::move e std::swap.
  • Especificadores não padronizados e desatualizados gostam throw() ou declspec(nothrow) não são equivalentes ao noexcept.

  • Especificadores explícitos e noexcept(true) são respeitados noexcept(false) adequadamente.

Exemplo

A ferramenta avisa em todas as funções, exceto o destruidor porque eles estão faltando noexcept.

struct S
{
    ~S() {}

    S(S&& s) {/*impl*/} // C26439, This kind of function may not throw. Declare it 'noexcept' (f.6)
    S& operator=(S&& s) {/*impl*/} // C26439, This kind of function may not throw. Declare it 'noexcept' (f.6)

    S(const S& s) {/*impl*/} // C26440, This function can be declared 'noexcept'
    S& operator=(const S& s) {/*impl*/} // C26440, This function can be declared 'noexcept'
};

Com noexcept a decoração da mesma estrutura, todos os avisos são removidos.

struct S
{
    ~S() {}

    S(S&& s) noexcept {/*impl*/}
    S& operator=(S&& s) noexcept {/*impl*/}

    S(const S& s) noexcept {/*impl*/}
    S& operator=(const S& s) noexcept {/*impl*/}
};

Confira também

C26455
Diretrizes principais do C++ F.6