O Perfil Vitalício das Diretrizes Principais do C ++, que faz parte das Diretrizes Principais do C ++ , visa detectar problemas de vida útil, como indicadores e referências pendentes, no código C ++. Ele usa as informações de tipo já presentes na fonte, juntamente com alguns contratos simples entre funções para detectar defeitos no tempo de compilação com anotação mínima.
Original no blogEstes são os contratos básicos que o perfil espera que o código siga:
- Não use um ponteiro potencialmente oscilante.
- Não passe um ponteiro potencialmente oscilante para outra função.
- Não retorne um ponteiro potencialmente danificado de nenhuma função.
Para obter mais informações sobre a história e os objetivos do perfil, consulte a publicação no blog de Herb Sutter sobre a versão 1.0 .
O que há de novo no Visual Studio 2019 Preview 2
Na Visualização 2, lançamos uma versão prévia do Lifetime Profile Checker, que implementa a versão publicada do Lifetime Profile . Esse verificador faz parte dos verificadores principais do C ++ no Visual Studio.
- Suporte para iteradores, string_views e spans.
- Melhor detecção de tipos personalizados de Proprietário e Ponteiro, o que permite que tipos personalizados se comportem como Contêineres, Ponteiros de Propriedade ou Ponteiros Não-Proprietários para participar da análise.
- As regras padrão de reconhecimento de tipo para condições de pré e pós chamada de função ajudam a reduzir falsos positivos e melhorar a precisão.
- Melhor suporte para tipos agregados.
- Correção geral e melhorias de desempenho.
- Alguma análise nullptr simples.
Ativando as regras do verificador de perfil vitalício
As regras do verificador não estão ativadas por padrão. Se você quiser experimentar as novas regras, precisará atualizar o conjunto de regras de análise de código selecionado para o seu projeto. Você pode selecionar as “Regras de tempo de vida útil da verificação principal do C ++” - que ativam apenas as regras do perfil de vida útil - ou pode modificar o conjunto de regras existente para ativar os avisos 26486 a 26489.

Captura de tela da página de propriedades Análise de código que mostra o conjunto de regras C ++ Core Check Lifetime Rules selecionado.
Os avisos aparecerão na Lista de erros quando a análise de código for executada (Analisar> Executar análise de código) ou, se você tiver a Análise de código em segundo plano ativada, os erros da vida útil aparecerão no editor com rabiscos verdes.

Captura de tela mostrando um aviso do Lifetime Profile Checker com um rabisco verde no código-fonte.
Exemplos
Ponteiro oscilante
O exemplo mais simples - usando um ponteiro pendente - é o melhor lugar para começar. Aqui, px
aponta para x
e, em seguida, x
deixa o escopo, deixando o px
dangling. Quando px
é usado, um aviso é emitido.
void simple_test() { int* px; { int x = 0; px = &x; } *px = 1;
Ponteiro de saída oscilante
Retornar ponteiros pendentes também não é permitido. Nesse caso, presume-se que o parâmetro ppx
seja um parâmetro de saída. Nesse caso, ele deve apontar para x
que fica fora do escopo no final da função. Isso deixa *ppx
pendente.
void out_parameter(int x, int** ppx)
Exibição de string pendente
Os dois últimos exemplos foram óbvios, mas instâncias temporárias podem introduzir erros sutis. Você pode encontrar o bug no código a seguir?
std::string get_string(); void dangling_string_view() { std::string_view sv = get_string(); auto c = sv.at(0); }
Nesse caso, a exibição de string sv
é construída com a instância de string temporária retornada de get_string()
. A sequência temporária é então destruída, o que deixa a exibição de sequência fazendo referência a um objeto inválido.
Iterador dangling
Outro problema de vida útil difícil de detectar ocorre ao usar um iterador inválido em um contêiner. No caso abaixo, a chamada para push_back
pode fazer com que o vetor realoque seu armazenamento subjacente, o que invalida o iterador.
void dangling_iterator() { std::vector<int> v = { 1, 2, 3 }; auto it = v.begin(); *it = 0;
Uma coisa a ser observada nesse exemplo é que não há tratamento especial para 'std :: vector :: push_back'. Esse comportamento cai fora das regras de perfil padrão. Uma regra classifica os contêineres como um 'Proprietário'. Em seguida, quando um método não-const é chamado no Proprietário, sua memória pertencente é considerada inválida e os iteradores que apontam para a memória pertencente também são considerados inválidos.
Proprietário modificado
O perfil é prescritivo em suas orientações. Ele espera que seu código use o sistema de tipos idiomamente ao definir parâmetros de função. Neste próximo exemplo, std::unique_ptr
, um tipo 'Proprietário', é passado para outra função por referência não const. De acordo com as regras do perfil, presume-se que os proprietários passados por referência não const sejam modificados pelo chamado.
void use_unique_ptr(std::unique_ptr<int>& upRef); void assumes_modification() { auto unique = std::make_unique<int>(0);
Neste exemplo, obtemos um ponteiro bruto, ptr
, para a memória pertencente a unique
. Então unique
é passado para a função use_unique_ptr
por referência não const. Como esse é um uso não constante de unique
onde a função pode fazer qualquer coisa, a análise assume que unique
'é invalidado de alguma forma (por exemplo, unique_ptr :: reset), o que causaria ptr
no ptr
.
Mais exemplos
Existem muitos outros casos que a análise pode detectar. Experimente no Visual Studio em seu próprio código e veja o que você encontra. Verifique também o blog de Herb para obter mais exemplos e, se você estiver curioso, leia o artigo do Lifetime Profile.
Problemas conhecidos
A implementação atual não suporta totalmente a análise, conforme descrito no documento do Perfil da vida útil. Aqui estão as categorias amplas que não são implementadas nesta versão.
Encerrar
Experimente o Verificador de perfil vitalício no Visual Studio 2019 Preview 2. Esperamos que ele ajude a identificar problemas de vida útil em seus projetos. Se você encontrar falsos positivos ou negativos, relate-os para que possamos priorizar os cenários que são importantes para você. Se você tiver sugestões ou problemas com essa verificação - ou qualquer recurso do Visual Studio - relate um problema ou publique na comunidade de desenvolvedores e informe-nos. Também estamos no Twitter em @VisualC .