Aviso C26414
"Mova, copie, reatribua ou redefina um ponteiro inteligente local."
Diretrizes Principais do C++:
R.5: Prefira objetos com escopo, não faça alocação por heap desnecessariamente
Ponteiros inteligentes são convenientes para o gerenciamento dinâmico de recursos, mas nem sempre são necessários. Por exemplo, pode ser mais fácil e eficiente gerenciar um buffer dinâmico local usando um contêiner padrão. Talvez você não precise de alocação dinâmica em objetos individuais, por exemplo, se eles nunca sobreviverem à função de criador. Eles podem ser substituídos por variáveis locais. Ponteiros inteligentes se tornam úteis quando um cenário requer uma alteração de propriedade. Por exemplo, quando você reatribui um recurso dinâmico várias vezes ou em vários caminhos. Eles também são úteis para recursos obtidos de código externo. E quando ponteiros inteligentes são usados para estender o tempo de vida de um recurso.
Comentários
Essa verificação reconhece os modelos std::unique_pointer
e std::shared_pointer
padrão e tipos definidos pelo usuário que provavelmente se destinam a ser ponteiros inteligentes. Esses tipos devem definir as seguintes operações:
operadores de desreferenciação ou acesso de membros sobrecarregados que são públicos e não marcados como excluídos;
um destruidor público que não é excluído nem definido como padrão. Isso inclui destruidores explicitamente definidos como vazios.
O tipo Microsoft::WRL::ComPtr
se comporta como um ponteiro compartilhado, mas geralmente é usado em cenários específicos que são afetados pelo gerenciamento de tempo de vida do COM. Para evitar ruído excessivo, esse tipo é filtrado.
Essa verificação procura alocações locais explícitas atribuídas a ponteiros inteligentes para identificar se as variáveis com escopo podem funcionar como alternativa. As chamadas diretas para o operador new
e funções especiais, como std::make_unique
e std::make_shared
, são interpretadas como alocações diretas.
Nome da análise de código: RESET_LOCAL_SMART_PTR
Exemplo
Buffer dinâmico:
void unpack_and_send(const frame &f)
{
auto buffer = std::make_unique<char[]>(f.size()); // C26414
f.unpack(buffer.get());
// ...
}
Buffer dinâmico substituído por contêiner:
void unpack_and_send(const frame &f)
{
auto buffer = std::vector<char>(f.size());
f.unpack(buffer.data());
// ...
}