C26439 SPECIAL_NOEXCEPT

"Esse tipo de função pode não lançar. Declare-o 'noexcept'."

Diretrizes Principais do C++ F.6: se sua função não for a lançar, declare-a noexcept

Alguns tipos de operações nunca devem causar exceções. Suas implementações devem ser confiáveis e devem lidar com possíveis condições de erros normalmente. Eles nunca 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 não podem transmitir suposições sobre sua confiabilidade.

Comentários

  • Os tipos especiais de operações são os seguintes:
    • destruidores;
    • construtores padrão;
    • mover construtores e mover operadores de atribuição;
    • funções padrão com semântica de movimentação: std::move e std::swap.
  • Especificadores não padrão e desatualizados, como throw() ou declspec(nothrow) não são equivalentes a 'noexcept'.
  • Especificadores explícitos noexcept(false) e noexcept(true) são respeitados adequadamente.
  • O aviso ainda pode aparecer para operações marcadas como constexpr. Isso pode mudar em versões futuras.

Exemplo

Todas as funções, exceto o destruidor, avisarão porque não há nenhumexcepto.

struct S
{
    S() {} // C26455, Default constructor may not throw. Declare it 'noexcept'
    ~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 decorando a mesma estrutura, todos os avisos são removidos.

struct S
{
    S() noexcept {}
    ~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*/}
};