Usar os verificadores de Diretrizes Principais do C++
As Diretrizes Principais do C++ são um conjunto portátil de diretrizes, regras e melhores práticas sobre codificação no C++ criado por especialistas e designers do C++. Atualmente, o Visual Studio dá suporte a um subconjunto dessas regras como parte de suas ferramentas de análise de código para C++. Os verificadores de diretrizes principais são instalados por padrão no Visual Studio 2017 e no Visual Studio 2019. Eles estão disponíveis como um pacote NuGet para o Visual Studio 2015.
O projeto de Diretrizes Principais do C++
Criadas por Bjarne Stroustrup e outros, as Diretrizes Principais do C++ são um guia para usar o C++ moderno de forma segura e eficaz. As Diretrizes enfatizam a segurança do tipo estático e a segurança de recursos. Identificam maneiras de eliminar ou minimizar as partes mais propensas a erros da linguagem de programação. Também sugerem como tornar seu código mais simples, mais confiável e ter um melhor desempenho. Essas diretrizes são mantidas pela Standard C++ Foundation. Para saber mais, consulte a documentação, Diretrizes Principais do C++ e acesse os arquivos de projeto de documentação das Diretrizes Principais do C++ no GitHub.
Habilitar as diretrizes de Verificação Principal do C++ em Code Analysis
Um subconjunto de regras de Verificação Principal do C++ está incluído no conjunto de regras do Microsoft Native Recommended. É o conjunto de regras executado por padrão quando a análise de código está habilitada.
Para habilitar a análise de código em seu projeto
Abra a caixa de diálogo Páginas de Propriedades do seu projeto.
Selecione a página de propriedades, Propriedades da Configuração>Code Analysis.
Selecione a caixa de seleção Habilitar Code Analysis ao Compilar.
Para habilitar mais regras de verificação principal, abra a lista suspensa e escolha quais conjuntos de regras você deseja incluir:
Um subconjunto de regras de Verificação Principal do C++ está incluído no conjunto de regras do Microsoft Native Recommended. É o conjunto de regras executado por padrão quando a análise de código da Microsoft está habilitada.
Para habilitar a análise de código em seu projeto:
Abra a caixa de diálogo Páginas de Propriedades do seu projeto.
Selecione a página de propriedades, Propriedades da Configuração>Code Analysis.
Defina as propriedades Habilitar Análise de Código no Build e Habilitar a Code Analysis da Microsoft.
Você também pode optar por executar todas as regras de Verificação Principal do C++ com suporte ou selecionar seu próprio subconjunto para executar:
Para habilitar mais regras de verificação principal
Abra a caixa de diálogo Páginas de Propriedades do seu projeto.
Selecione a página de propriedades, Propriedades da Configuração>Code Analysis>Microsoft.
Abra a lista suspensa Regras Ativas e selecione Escolher vários conjuntos de regras.
Na caixa de diálogo Adicionar ou Remover Conjuntos de Regras, escolha quais conjuntos de regras você deseja incluir.
Exemplos
Aqui está um exemplo de alguns dos problemas que as regras de Verificação Principal do C++ podem encontrar:
// CoreCheckExample.cpp
// Add CppCoreCheck package and enable code analysis in build for warnings.
int main()
{
int arr[10]; // warning C26494
int* p = arr; // warning C26485
[[gsl::suppress(bounds.1)]] // This attribute suppresses Bounds rule #1
{
int* q = p + 1; // warning C26481 (suppressed)
p = q++; // warning C26481 (suppressed)
}
return 0;
}
Este exemplo demonstra alguns dos avisos que as regras de Verificação Principal do C++ podem encontrar:
C26494 é a regra Type.5: sempre inicializar um objeto.
C26485 é a regra Bounds.3: nenhum decaimento de matriz para ponteiro.
C26481 é a regra Bounds.1: não use aritmética de ponteiro. Use
span
em vez disso.
Instale e habilite os conjuntos de regras de análise de código da Verificação Principal do C++ e, em seguida, compile esse código. A análise de código gera os dois primeiros avisos e suprime o terceiro. Aqui está a saída da compilação do código de exemplo no Visual Studio 2015:
1>------ Build started: Project: CoreCheckExample, Configuration: Debug Win32 ------
1> CoreCheckExample.cpp
1> CoreCheckExample.vcxproj -> C:\Users\username\documents\visual studio 2015\Projects\CoreCheckExample\Debug\CoreCheckExample.exe
1> CoreCheckExample.vcxproj -> C:\Users\username\documents\visual studio 2015\Projects\CoreCheckExample\Debug\CoreCheckExample.pdb (Full PDB)
c:\users\username\documents\visual studio 2015\projects\corecheckexample\corecheckexample\corecheckexample.cpp(6): warning C26494: Variable 'arr' is uninitialized. Always initialize an object. (type.5: http://go.microsoft.com/fwlink/p/?LinkID=620421)
c:\users\username\documents\visual studio 2015\projects\corecheckexample\corecheckexample\corecheckexample.cpp(7): warning C26485: Expression 'arr': No array to pointer decay. (bounds.3: http://go.microsoft.com/fwlink/p/?LinkID=620415)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
As Diretrizes Principais do C++ estão lá para ajudá-lo a escrever um código melhor e mais seguro. No entanto, você pode encontrar uma instância em que uma regra ou um perfil não deve ser aplicado. É fácil suprimi-lo diretamente no código. Você pode usar o atributo [[gsl::suppress]]
para impedir que a Verificação Principal do C++ detecte e reporte qualquer violação de regra no bloco de código a seguir. Você pode marcar instruções individuais para suprimir regras específicas. Você pode até mesmo suprimir todo o perfil de limites escrevendo [[gsl::suppress(bounds)]]
sem incluir um número de regra específico.
Conjuntos de regras com suporte
À medida que novas regras são adicionadas ao Verificador de Diretrizes Principais do C++, o número de avisos produzidos para código pré-existente pode aumentar. Você pode usar conjuntos de regras predefinidos para filtrar quais tipos de regras habilitar. Você encontrará artigos de referência para a maioria das regras em Referência de Verificação Principal do C++ do Visual Studio.
Regras aritméticas: regras para detectar estouro aritmético, operações signed-unsigned e manipulação de bits.15.6
Regras de limites: impor o Perfil de limites das Diretrizes Principais do C++.15.3
Regras de classe: algumas regras que se concentram no uso adequado de funções de membro especiais e especificações virtuais. Eles são um subconjunto das verificações recomendadas para classes e hierarquias de classe.15.5
Regras de simultaneidade: uma única regra, que captura declarações de objeto de proteção incorreta. Para obter mais informações, consulte as diretrizes relacionadas à simultaneidade.15.5
Regras const: impor verificações relacionadas a const das Diretrizes Principais do C++.15.3
Regras de declaração: algumas regras das diretrizes de interfaces que se concentram em como as variáveis globais são declaradas.15.5
Regras de enumeração: essas regras impõem verificações relacionadas à enumeração das Diretrizes Principais do C++.16.3
Regras experimentais Estas são regras experimentais de Verificação Principal do C++ que são úteis, mas não estão prontas para uso diário. Experimente-as e forneça comentários.16.0
Regras de função: duas verificações que ajudam na adoção do especificador
noexcept
. Elas fazem parte das diretrizes para design e implementação de funções de limpeza.15.5Regras de GSL: essas regras impõem verificações relacionadas à Biblioteca de Suporte de Diretrizes das Diretrizes Principais do C++.15.7
Regras de tempo de vida: essas regras impõem o perfil de tempo de vida das Diretrizes Principais do C++.15.7
Regras de ponteiro do proprietário: impor verificações de gerenciamento de recursos relacionadas ao proprietário<T> das Diretrizes Principais do C++.15.3
Regras de ponteiro bruto: impor verificações de gerenciamento de recursos relacionadas a ponteiros brutos das Diretrizes Principais do C++.15.3
Regras de ponteiro compartilhado: faz parte da imposição de diretrizes de gerenciamento de recursos. 15.5 Adicionamos algumas regras específicas de como ponteiros compartilhados são passados para funções ou usados localmente.
Regras de STL: essas regras impõem verificações relacionadas à STL (Biblioteca Padrão C++) das Diretrizes Principais do C++.15.7
Regras de estilo: uma verificação simples, mas importante, que proíbe o uso de goto.15.5. É a primeira etapa para melhorar o estilo de codificação e o uso de expressões e instruções no C++.
Regras de tipo: impor o perfil tipo das Diretrizes Principais do C++.15.3
Regras de ponteiro exclusivas: impor verificações de gerenciamento de recursos relacionadas a tipos com semântica de ponteiro exclusiva das Diretrizes Principais do C++.15.3
Regras de verificação do C++ Core: esse conjunto de regras contém todas as verificações implementadas no momento das Diretrizes Principais do C++, exceto para as regras Experimentais.
15.3 Essas regras apareceram pela primeira vez no Visual Studio 2017 versão 15.3
15.5 Essas regras apareceram pela primeira vez no Visual Studio 2017 versão 15.5
15.6 Essas regras apareceram pela primeira vez no Visual Studio 2017 versão 15.6
15.7 Essas regras apareceram pela primeira vez no Visual Studio 2017 versão 15.7
16.0 Essas regras apareceram pela primeira vez no Visual Studio 2019 versão 16.0
16.3 Essas regras apareceram pela primeira vez no Visual Studio 2019 versão 16.3
Você pode optar por limitar os avisos a apenas um ou alguns dos grupos. Os conjuntos de regras nativos mínimos e nativos recomendados incluem regras de Verificação Principal do C++ e outras verificações PREfast.
Para ver os conjuntos de regras disponíveis, abra a caixa de diálogo Propriedades do Projeto. Na caixa de diálogo Páginas de Propriedades, selecione a página de propriedade Propriedades de Configuração>Code Analysis>Geral. Em seguida, abra a lista suspensa na caixa de combinação Conjuntos de Regras para ver os conjuntos de regras disponíveis. Para criar uma combinação personalizada de conjuntos de regras, selecione Escolher vários conjuntos de regras. A caixa de diálogo Adicionar ou Remover Conjuntos de Regras lista as regras que você pode escolher. Para obter mais informações sobre como usar conjuntos de regras no Visual Studio, consulte Usar conjuntos de regras para especificar as regras do C++ a serem executadas.
Para ver os conjuntos de regras disponíveis, abra a caixa de diálogo Propriedades do Projeto. Na caixa de diálogo Páginas de Propriedades, selecione a página de propriedade Propriedades de Configuração>Code Analysis>Microsoft. Em seguida, abra a lista suspensa na caixa de combinação Regras Ativas para ver os conjuntos de regras disponíveis. Para criar uma combinação personalizada de conjuntos de regras, selecione Escolher vários conjuntos de regras. A caixa de diálogo Adicionar ou Remover Conjuntos de Regras lista as regras que você pode escolher. Para obter mais informações sobre como usar conjuntos de regras no Visual Studio, consulte Usar conjuntos de regras para especificar as regras do C++ a serem executadas.
Macros
O Verificador de Diretrizes Principais do C++ vem com um arquivo de cabeçalho, que define macros que facilitam a supressão de categorias inteiras de avisos no código:
ALL_CPPCORECHECK_WARNINGS
CPPCORECHECK_TYPE_WARNINGS
CPPCORECHECK_RAW_POINTER_WARNINGS
CPPCORECHECK_CONST_WARNINGS
CPPCORECHECK_OWNER_POINTER_WARNINGS
CPPCORECHECK_UNIQUE_POINTER_WARNINGS
CPPCORECHECK_BOUNDS_WARNINGS
Essas macros correspondem aos conjuntos de regras e se expandem para uma lista separada por espaço de números de aviso. Usando os constructos de pragma apropriados, você pode configurar o conjunto efetivo de regras que seja interessante para um projeto ou uma seção de código. No exemplo a seguir, a análise de código alerta apenas sobre modificadores constantes ausentes:
#include <CppCoreCheck\Warnings.h>
#pragma warning(disable: ALL_CPPCORECHECK_WARNINGS)
#pragma warning(default: CPPCORECHECK_CONST_WARNINGS)
Atributos
O compilador do Microsoft C++ tem suporte limitado para o atributo [[gsl::suppress]]
. Ele pode ser usado para suprimir avisos em instruções de expressão e de bloqueio dentro das funções.
// Suppress only warnings from the 'r.11' rule in expression.
[[gsl::suppress(r.11)]] new int;
// Suppress all warnings from the 'r' rule group (resource management) in block.
[[gsl::suppress(r)]]
{
new int;
}
// Suppress only one specific warning number.
// For declarations, you might need to use the surrounding block.
// Macros are not expanded inside of attributes.
// Use plain numbers instead of macros from the warnings.h.
[[gsl::suppress(26400)]]
{
int *p = new int;
}
Suprimir a análise usando opções de linha de comando
Em vez de #pragmas, você pode usar opções de linha de comando na página de propriedade do arquivo para suprimir avisos para um projeto ou para um único arquivo. Por exemplo, para desabilitar o aviso C26400 para um arquivo:
Clique com o botão direito do mouse no nó do projeto no Gerenciador de Soluções e selecione Propriedades.
Na caixa de diálogo Páginas de Propriedades, selecione a página de propriedade Propriedades de Configuração>C/C++>Linha de Comando.
Na caixa de edição Opções Adicionais, adicione
/wd26400
.
Você pode usar a opção de linha de comando para desabilitar temporariamente todas as análises de código para um arquivo especificando /analyze-
. Você verá o aviso D9025 substituindo '/analyze' com '/analyze-', o que lembra que você reabilitará a análise de código mais tarde.
Habilitar o Verificador de Diretrizes Principais do C++ em arquivos de projeto específico
Às vezes, é útil fazer a análise de código focada e ainda usar o IDE do Visual Studio. Experimente o cenário de amostra a seguir para projetos grandes. Ele pode economizar tempo de compilação e facilitar a filtragem de resultados:
No shell de comando, defina a
esp.extension
variável de ambiente.Para herdar essa variável, abra o Visual Studio no shell de comando.
Carregue o projeto e abra suas propriedades.
Habilite a análise de código, escolha os conjuntos de regras apropriados, mas não habilite as extensões de análise de código.
Vá para o arquivo que deseja analisar com o Verificador de Diretrizes Principais do C++ e abra suas propriedades.
Escolha Propriedades de configuração>C/C++>Linha de comando>Opções Adicionais e adicione
/analyze:plugin EspXEngine.dll
Desabilite o uso de cabeçalho pré-compilado (de Configuração>C/C++>Cabeçalhos pré-compilados). É necessário porque o mecanismo de extensões pode tentar ler suas informações internas do cabeçalho pré-compilado (PCH). Se o PCH foi compilado com opções de projeto padrão, ele não será compatível.
Recompile o projeto. As verificações PREFast comuns devem ser executadas em todos os arquivos. Como o Verificador de Diretrizes Principais do C++ não está habilitado por padrão, ele só deve ser executado no arquivo configurado para usá-lo.
Como usar o Verificador de Diretrizes Principais do C++ fora do Visual Studio
Você pode usar as verificações de Diretrizes Principais do C++ em builds automatizados.
MSBuild
O verificador de Code Analysis Nativo (PREfast) é integrado ao ambiente MSBuild por arquivos de destino personalizados. Você pode usar as propriedades do projeto para habilitá-lo e adicionar o Verificador de Diretrizes Principais do C++ (que se baseia em PREfast):
<PropertyGroup>
<EnableCppCoreCheck>true</EnableCppCoreCheck>
<CodeAnalysisRuleSet>CppCoreCheckRules.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
Adicione essas propriedades antes da importação do arquivo Microsoft.Cpp.targets
. Você pode escolher conjuntos de regras específicos ou criar um conjunto de regras personalizado. Ou usar o conjunto de regras padrão que inclui outras verificações PREfast.
Você pode executar o Verificador Principal do C++ somente em arquivos especificados. Use a mesma abordagem descrita anteriormente, mas use arquivos MSBuild. As variáveis de ambiente podem ser definidas usando o item BuildMacro
:
<ItemGroup>
<BuildMacro Include="Esp_Extensions">
<EnvironmentVariable>true</EnvironmentVariable>
<Value>CppCoreCheck.dll</Value>
</BuildMacro>
</ItemGroup>
Se você não quiser modificar o arquivo de projeto, poderá passar propriedades na linha de comando:
msbuild /p:EnableCppCoreCheck=true /p:RunCodeAnalysis=true /p:CodeAnalysisRuleSet=CppCoreCheckRules.ruleset ...
Projetos não MSBuild
Se você usar um sistema de build que não depende do MSBuild, ainda poderá executar o verificador. Para usá-lo, você precisa se familiarizar com alguns internos da configuração do mecanismo do Code Analysis. Não garantimos suporte para esses internos em versões futuras do Visual Studio.
O Code Analysis requer algumas variáveis de ambiente e opções de linha de comando do compilador. Recomendamos que você use o ambiente do Prompt de Comando de Ferramentas Nativas para que não precise pesquisar caminhos específicos para o compilador, incluir diretórios e assim por diante.
Variáveis de ambiente
set esp.extensions=cppcorecheck.dll
Isso informa ao mecanismo para carregar o módulo Diretrizes Principais do C++.- Desde o Visual Studio 2019, não recomendamos mais definir a variável de ambiente,
esp.annotationbuildlevel
pois defini-la pode resultar em falsos positivos. Se vir resultados inesperados, remova essa variável do seu ambiente. set caexcludepath=%include%
É altamente recomendável desabilitar avisos que disparam em cabeçalhos padrão. Você pode adicionar mais caminhos aqui, por exemplo, o caminho para os cabeçalhos comuns em seu projeto.
Opções da linha de comando
/analyze
Habilita a análise de código (considere também usar/analyze:only
e/analyze:quiet
)./analyze:plugin EspXEngine.dll
Essa opção carrega o mecanismo de Extensões do Code Analysis no PREfast. Esse mecanismo, por sua vez, carrega o Verificador de Diretrizes Principais do C++.
Usar a Biblioteca de Suporte de Diretrizes
A GSL (Biblioteca de Suporte de Diretrizes) foi projetada para ajudá-lo a seguir as Diretrizes Principais. A GSL inclui definições que permitem substituir constructos propensos a erros por alternativas mais seguras. Por exemplo, você pode substituir um par de parâmetros T*, length
pelo tipo span<T>
. O projeto da GSL está disponível no GitHub em https://github.com/Microsoft/GSL. A biblioteca é de software livre, para que você possa exibir as fontes, fazer comentários ou contribuir. Você também pode usar o gerenciador de pacotes vcpkg para baixar e instalar a biblioteca localmente.
Usar as diretrizes de Verificação Principal do C++ em projetos do Visual Studio 2015
Se você usar o Visual Studio 2015, os conjuntos de regras de análise de código de Verificação Principal do C++ não serão instalados por padrão. Outras etapas são necessárias antes que você possa habilitar as ferramentas de análise de código do C++ Core Check no Visual Studio 2015. A Microsoft oferece suporte para projetos do Visual Studio 2015 usando um pacote NuGet. O pacote se chama Microsoft.CppCoreCheck e está disponível em http://www.nuget.org/packages/Microsoft.CppCoreCheck. Esse pacote exige que você tenha pelo menos o Visual Studio 2015 com a Atualização 1 instalada.
O pacote também instala outro pacote como uma dependência, somente o cabeçalho da GSL (Biblioteca de Suporte de Diretrizes). A GSL também está disponível no GitHub em https://github.com/Microsoft/GSL.
Devido à maneira como as regras de análise de código são carregadas no Visual Studio 2015, você deve instalar o pacote NuGet Microsoft.CppCoreCheck
em cada projeto C++ que deseja verificar.
Para adicionar o pacote Microsoft.CppCoreCheck ao seu projeto no Visual Studio 2015
Em Gerenciador de Soluções, clique com o botão direito do mouse para abrir o menu de contexto do projeto na solução para a qual você deseja adicionar o pacote. Escolha Gerenciar Pacotes NuGet para abrir o Gerenciador de Pacotes NuGet.
Na janela Gerenciador de pacotes NuGet, pesquise por Microsoft.CppCoreCheck.
Selecione o pacote Microsoft.CppCoreCheck e escolha o botão Instalar para adicionar as regras ao projeto.
O pacote NuGet adiciona um arquivo MSBuild
.targets
ao seu projeto que é chamado quando você habilita a análise de código em seu projeto. O.targets
arquivo adiciona as regras de verificação principal do C++ como outra extensão para a ferramenta de análise de código do Visual Studio. Quando o pacote é instalado, você pode usar a caixa de diálogo Páginas de Propriedades para habilitar ou desabilitar as regras liberadas e experimentais.