Aviso C26440
A função pode ser declarada «noexcept».
Diretrizes principais do C++ F.6: Se sua função não for lançada, declare-a noexcept
Se o código não deve causar exceções, ele deve ser marcado usando o noexcept
especificador. Essa anotação ajuda a simplificar o tratamento de erros no lado do código do cliente e permite que o compilador faça mais otimizações.
Comentários
- Uma função é considerada não arremessadora se:
- não tem declarações explícitas
throw
; - As chamadas de função em seu corpo, se houver, invocam apenas funções que são improváveis de lançar:
constexpr
ou funções marcadas com qualquer especificação de exceção que implique comportamento de não lançamento (incluindo algumas especificações não padrão).
- não tem declarações explícitas
- Especificadores não padronizados e desatualizados gostam
throw()
ou__declspec(nothrow)
não são equivalentes aonoexcept
. - Especificadores explícitos e
noexcept(true)
são respeitadosnoexcept(false)
adequadamente. - As funções marcadas como
constexpr
não devem causar exceções e não são analisadas. - A regra também se aplica a expressões lambda.
- A lógica não considera chamadas recursivas como potencialmente não geradoras. Essa lógica pode mudar no futuro.
Exemplo
Todas as funções, exceto o destruidor avisará porque eles estão faltando noexexceto.
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 o 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*/}
};