Partilhar via


/external (diagnóstico de cabeçalhos externos)

As opções do compilador /external permitem especificar o comportamento de diagnóstico do compilador para determinados arquivos de cabeçalho. Cabeçalhos "externos" são o complemento natural de "Apenas Meu Código": arquivos de cabeçalho, como arquivos de sistema ou arquivos de biblioteca de terceiros que você não pode ou não pretende alterar. Como não vai alterar esses arquivos, você pode decidir que não é útil ver mensagens de diagnóstico do compilador sobre eles. As opções do compilador /external fornecem controle sobre esses avisos.

A opção do compilador /external estão disponíveis começando no Visual Studio 2017 versão 15.6. Nas versões do Visual Studio anteriores ao Visual Studio 2019 versão 16.10, as opções /external exigem que você também defina a opção do compilador /experimental:external.

Sintaxe

Usar opções de cabeçalho externo (não obrigatório na versão 16.10 e posteriores):

/experimental:external

Especificar cabeçalhos externos:

/external:anglebrackets
/external:env:var
/external:I path

Especificar o comportamento de diagnóstico:

/external:W0
/external:W1
/external:W2
/external:W3
/external:W4
/external:templates-

Argumentos

/experimental:external
Habilita as opções de cabeçalhos externos. Essa opção não é obrigatória no Visual Studio 2019 versão 16.10 e posteriores.

/external:anglebrackets
Trata todos os cabeçalhos incluídos por #include <header>, em que o arquivo header está entre colchetes angulares (< >), como cabeçalhos externos.

/external:I path
Define um diretório raiz que contém cabeçalhos externos. Todos os subdiretórios recursivos de path são considerados externos, mas apenas o valor path é adicionado à lista de diretórios em que o compilador pesquisa por arquivos incluídos. O espaço entre /external:I e path é opcional. Diretórios que incluem espaços devem ser colocados entre aspas duplas. Um diretório pode ser um caminho absoluto ou um caminho relativo.

/external:env:var
Especifica o nome de uma variável de ambiente var que contém uma lista separada por ponto e vírgula de diretórios de cabeçalho externos. É útil para sistemas de build que dependem de variáveis de ambiente como INCLUDE, que você usa para especificar a lista de arquivos incluídos externos. Ou CAExcludePath para arquivos que não devem ser analisados por /analyze. Por exemplo, você pode especificar /external:env:INCLUDE para transformar todos os diretórios em INCLUDE em um diretório de cabeçalho externo de uma só vez. É o mesmo que usar /external:I para especificar os diretórios individuais, mas muito menos detalhado. Não deve haver espaço entre var e /external:env:.

/external:Wn
Essa opção define o nível de aviso padrão como n (um valor de 0 a 4) para cabeçalhos externos. Por exemplo, /external:W0 desativa os avisos para cabeçalhos externos. Se essa opção não for especificada, o compilador emitirá o aviso de linha de comando D9007 para outras opções de /external. Essas opções são ignoradas porque não teriam efeito.

A opção /external:Wn tem um efeito semelhante ao encapsulamento de um cabeçalho incluído em uma diretiva #pragma warning:

#pragma warning (push, 0)
// the global warning level is now 0 here
#include <external_header>
#pragma warning (pop)

/external:templates-
Permite avisos de cabeçalhos externos quando eles ocorrem em um modelo instanciado em seu código.

Comentários

Por padrão, o nível de aviso /Wn especificado para o build se aplica a todos os arquivos. As opções para especificar cabeçalhos externos definem apenas um conjunto de arquivos ao qual você pode aplicar um nível de aviso padrão diferente. Portanto, se você especificar cabeçalhos externos, também use /external:Wn para especificar um nível de aviso externo para alterar o comportamento do compilador.

Todos os mecanismos existentes para habilitar, desabilitar e suprimir avisos ainda funcionam em arquivos externos e não externos. Por exemplo, um pragma warning ainda pode substituir o nível de aviso padrão definido para cabeçalhos externos.

Exemplo: definir o nível de aviso externo

Este programa de exemplo tem dois arquivos de origem, program.cpp e header_file.h. O arquivo header_file.h está em um subdiretório include_dir do diretório que contém o arquivo program.cpp:

Arquivo de origem include_dir/header_file.h:

// External header: include_dir/header_file.h

template <typename T>
struct sample_struct
{
    static const T value = -7; // W4: warning C4245: 'initializing':
    // conversion from 'int' to 'unsigned int', signed/unsigned mismatch
};

Arquivo de origem program.cpp:

// User code: program.cpp
#include <header_file.h>

int main()
{
    return sample_struct<unsigned int>().value;
}

Você pode compilar o exemplo usando esta linha de comando:

cl /EHsc /I include_dir /W4 program.cpp

Conforme o esperado, o exemplo gera um aviso:

program.cpp
include_dir\header_file.h(6): warning C4245: 'initializing': conversion from 'int' to 'const T', signed/unsigned mismatch
        with
        [
            T=unsigned int
        ]
program.cpp(6): note: see reference to class template instantiation 'sample_struct<unsigned int>' being compiled

Para tratar o arquivo de cabeçalho como um arquivo externo e suprimir o aviso, você pode usar esta linha de comando*:

cl /EHsc /I include_dir /external:anglebrackets /external:W0 /W4 program.cpp

Ela suprime o aviso dentro de header_file.h enquanto preserva os avisos dentro de program.cpp.

Avisos nos limites interno e externo

Definir um nível de aviso baixo para cabeçalhos externos pode ocultar alguns avisos acionáveis. Em particular, pode desativar avisos emitidos em instanciações de modelo no código do usuário. Esses avisos podem indicar um problema no código que só acontece em instanciações para tipos específicos. (Por exemplo, se você esqueceu de aplicar uma característica de tipo removendo const ou &.) Para evitar silenciar avisos dentro de modelos definidos em cabeçalhos externos, você pode usar a opção /external:templates-. O compilador considera o nível de aviso efetivo no arquivo que define o modelo e o nível de aviso em que ocorre a instanciação do modelo. Os avisos emitidos dentro de um modelo externo aparecerão se o modelo for instanciado em um código não externo. Por exemplo, esta linha de comando reabilita avisos de fontes de modelo no código de exemplo*:

cl /EHsc /I include_dir /external:anglebrackets /external:W0 /external:templates- /W4 program.cpp

O aviso C4245 aparece novamente na saída, mesmo que o código de modelo esteja dentro de um cabeçalho externo.

Habilitar, desabilitar ou suprimir avisos

Todos os mecanismos existentes para habilitar, desabilitar e suprimir avisos ainda funcionam em cabeçalhos externos. Quando aparece um aviso porque você usa a opção /external:templates-, você ainda pode suprimir o aviso no ponto de instanciação. Por exemplo, para suprimir explicitamente o aviso no exemplo que reaparece por causa de /external:templates-, use uma diretiva pragma warning:

int main()
{
    #pragma warning( suppress : 4245)
    return sample_struct<unsigned int>().value;
}

Escritores de bibliotecas poderão usar os mesmos mecanismos para impor determinados avisos, ou todos os avisos em determinado nível, se acharem que esses avisos nunca devem ser silenciados por /external:Wn. Por exemplo, esta versão do arquivo de cabeçalho força o aviso C4245 a relatar um erro:

// External header: include_dir/header_file.h

#pragma warning( push, 4 )
#pragma warning( error : 4245 )

template <typename T>
struct sample_struct
{
    static const T value = -7; // W4: warning C4245: 'initializing': conversion from 'int'
                               // to 'unsigned int', signed/unsigned mismatch
};

#pragma warning( pop )

Com essa alteração no cabeçalho da biblioteca, o autor da biblioteca garante que o nível de aviso global neste cabeçalho seja 4, independentemente do que for especificado em /external:Wn. Agora, todos os avisos de nível 4 e acima são relatados. O autor da biblioteca também pode forçar certos avisos a serem erros, desabilitados, suprimidos ou emitidos apenas uma vez no cabeçalho. As opções /external não substituem essa escolha deliberada.

Pragma system_header

#pragma system_header é um marcador intrusivo que permite que os escritores de biblioteca marquem determinados cabeçalhos como externos. Um arquivo que contém #pragma system_header é considerado externo do ponto do pragma até o final do arquivo, como se tivesse sido especificado como externo na linha de comando. O compilador emite qualquer diagnóstico após o pragma no nível de aviso especificado por /external:Wn. Para obter mais informações, consulte pragma system_header.

Limitações

Alguns avisos emitidos pela geração de código de back-end do compilador não são afetados pelas opções /external. Esses avisos geralmente começam com C47XX, embora nem todos os avisos C47XX sejam avisos de back-end. Você ainda pode desabilitá-los individualmente usando /wd47XX. Os avisos de análise de código também não são afetados, pois não têm níveis de aviso.

Para definir esta opção do compilador no ambiente de desenvolvimento do Visual Studio

No Visual Studio 2019 versão 16.10 e posteriores:

  1. Abra a caixa de diálogo Páginas de Propriedades do projeto. Para obter detalhes, confira Definir as propriedades de build e do compilador do C++ no Visual Studio.

  2. Selecione a página de Propriedades de Configuração>Diretórios VC++.

  3. Defina a propriedade Diretórios de Inclusão Externos para especificar o equivalente no IDE da opção /external:I path para cada caminho delimitado por ponto e vírgula.

  4. Selecione a página de propriedades Propriedades da Configuração>C/C++>Inclui Externo.

  5. Defina as propriedades:

    • Defina Tratar arquivos incluídos com colchetes angulares como externos como Sim para definir a opção /external:anglebrackets.

    • O Nível de aviso de cabeçalho externo permite que você defina a opção /external:Wn. Se esse valor for definido como Herdar o nível de aviso do projeto ou o padrão, outras opções /external serão ignoradas.

    • Defina o Diagnóstico de modelo em cabeçalhos externos como Sim para definir a opção /external:templates-.

  6. Escolha OK ou Aplicar para salvar as alterações.

Nas versões do Visual Studio anteriores ao Visual Studio 2019 versão 16.10:

  1. Abra a caixa de diálogo Páginas de Propriedades do projeto. Para obter detalhes, confira Definir as propriedades de build e do compilador do C++ no Visual Studio.

  2. Selecione a página de propriedades Propriedades de Configuração>C/C++>Linha de Comando.

  3. Insira a opção /experimental:external e outras opções do compilador /external na caixa Opções Adicionais.

  4. Escolha OK ou Aplicar para salvar as alterações.

Para definir essa opção do compilador via programação

* Adicione a opção /experimental:external para habilitar as opções de cabeçalhos externos em versões do Visual Studio anteriores ao Visual Studio 2019 versão 16.10.

Confira também

Opções do compilador MSVC
Sintaxe de linha de comando do compilador MSVC