/external (Diagnóstico de encabezados externos)

Las opciones del compilador /external permiten especificar el comportamiento de diagnóstico del compilador para determinados archivos de encabezado. Los encabezados "externos" son el complemento natural de "Solo mi código": los archivos de encabezado, como los del sistema o de biblioteca de terceros que no se pueden cambiar o que no quiere cambiar. Dado que no cambiará estos archivos, puede que no le parezca útil ver los mensajes de diagnóstico sobre ellos del compilador. Las opciones del compilador /external proporcionan control sobre estas advertencias.

La opción del compilador /external está disponible a partir de la versión 15.6 de Visual Studio 2017. En versiones de Visual Studio anteriores a la versión 16.10 de Visual Studio 2019, las opciones /external requieren que también establezca la opción del compilador /experimental:external.

Sintaxis

Use opciones de encabezado externo (no necesarias en la versión 16.10 y posteriores):

/experimental:external

Especificar encabezados externos:

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

Especificar el comportamiento de diagnóstico:

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

Argumentos

/experimental:external
Habilita las opciones de encabezados externos. Esta opción no es necesaria en la versión 16.10 de Visual Studio 2019 y posteriores.

/external:anglebrackets
Trata todos los encabezados incluidos por #include <header>, donde el archivo header se incluye entre paréntesis angulares (< >) como encabezados externos.

/external:I path
Define un directorio raíz que contiene encabezados externos. Todos los subdirectorios recursivos de path se consideran externos, pero solo se agrega el valor path a la lista de directorios en la que el compilador busca archivos de inclusión. El espacio entre /external:I y path es opcional. Los directorios que incluyen espacios deben incluirse entre comillas dobles. Un directorio puede ser una ruta de acceso absoluta o una ruta de acceso relativa.

/external:env:var
Especifica el nombre de una variable de entorno var que contiene una lista de directorios de encabezados externos separados por punto y coma. Resulta útil para los sistemas de compilación que se basan en variables de entorno como INCLUDE, que se usa para especificar la lista de archivos de inclusión externos. O bien CAExcludePath para los archivos que no deben analizarse mediante /analyze. Por ejemplo, puede especificar /external:env:INCLUDE para que todos los directorios de INCLUDE sean directorios de encabezado externo a la vez. Es lo mismo que usar /external:I para especificar los directorios individuales, pero mucho menos complicado. No debe haber ningún espacio entre var y /external:env:.

/external:Wn
Esta opción establece el nivel de advertencia predeterminado en n (un valor de 0 a 4) para los encabezados externos. Por ejemplo, /external:W0 desactiva eficazmente las advertencias de los encabezados externos. Si no se especifica esta opción, el compilador emite la advertencia de línea de comandos D9007 para otras opciones /external. Esas opciones se omiten, ya que no tendrán ningún efecto.

La opción /external:Wn tiene un efecto similar al ajuste de un encabezado incluido en una directiva #pragma warning:

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

/external:templates-
Permite advertencias de encabezados externos cuando se producen en una plantilla de la que se crea una instancia en el código.

Comentarios

De forma predeterminada, el nivel de advertencia /Wn que especifique para la compilación se aplica a todos los archivos. Las opciones para especificar encabezados externos solo definen un conjunto de archivos en los que puede aplicar otro nivel de advertencia predeterminado. Por lo tanto, si especifica encabezados externos, use también /external:Wn para especificar un nivel de advertencia externo a fin de cambiar el comportamiento del compilador.

Todos los mecanismos actuales para habilitar, deshabilitar y suprimir advertencias siguen funcionando en archivos externos y no externos. Por ejemplo, una pragma warning todavía puede invalidar el nivel de advertencia predeterminado establecido para los encabezados externos.

Ejemplo: Establecimiento del nivel de advertencia externo

Este programa de ejemplo tiene dos archivos de origen, program.cpp y header_file.h. El archivo header_file.h está en un subdirectorio include_dir del directorio que contiene el archivo program.cpp:

Archivo de origen 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
};

Archivo de origen program.cpp:

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

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

Puede compilar el ejemplo mediante esta línea de comandos:

cl /EHsc /I include_dir /W4 program.cpp

Tal como se esperaba, este ejemplo genera una advertencia:

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 el archivo de encabezado como un archivo externo y suprimir la advertencia, puede usar esta línea de comandos en su lugar*:

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

Esta línea de comandos suprime la advertencia de header_file.h y conserva las de program.cpp.

Advertencias en los límites interno y externo

Establecer un nivel de advertencia bajo para los encabezados externos puede ocultar algunas advertencias que requieren acción. En concreto, puede desactivar las advertencias emitidas en las creaciones de instancias de plantilla del código de usuario. Estas advertencias pueden indicar un problema en el código que solo se produce en las creaciones de instancias de determinados tipos. (Por ejemplo, si ha olvidado aplicar un rasgo de tipo quitando const o &). Para evitar que se silencien advertencias dentro de las plantillas definidas en encabezados externos, puede usar la opción /external:templates-. El compilador considera tanto el nivel de advertencia efectivo en el archivo que define la plantilla como el nivel de advertencia en el que se produce la creación de instancias de plantilla. Las advertencias emitidas dentro de una plantilla externa aparecen si se crea una instancia de la plantilla en código no externo. Por ejemplo, esta línea de comandos vuelve a habilitar advertencias de orígenes de plantilla en el código de ejemplo*:

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

La advertencia C4245 aparece de nuevo en la salida aunque el código de plantilla esté dentro de un encabezado externo.

Habilitación, deshabilitación o eliminación de advertencias

Todos los mecanismos actuales para habilitar, deshabilitar y eliminar advertencias siguen funcionando en encabezados externos. Cuando aparece una advertencia porque usa la opción /external:templates-, todavía puede suprimir la advertencia en el punto de creación de instancias. Por ejemplo, para suprimir explícitamente la advertencia en el ejemplo que vuelve a aparecer debido a /external:templates-, use una directiva pragma warning:

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

Los escritores de bibliotecas pueden usar los mismos mecanismos para aplicar ciertas advertencias, o todas las advertencias en un determinado nivel, si creen que /external:Wn nunca debería silenciarlas. Por ejemplo, esta versión del archivo de encabezado fuerza la advertencia C4245 para notificar un error:

// 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 )

Con este cambio en el encabezado de biblioteca, el autor de la biblioteca garantiza que el nivel de advertencia global de este encabezado sea 4, independientemente de lo que se especifique en /external:Wn. Ahora se notifican todas las advertencias de nivel 4 y superiores. El autor de la biblioteca también puede forzar que ciertas advertencias sean errores, se deshabiliten, se eliminen o se omitan solo una vez en el encabezado. Las opciones /external no invalidan esa elección deliberada.

system_header pragma

#pragma system_header es un marcador intrusivo que permite a los escritores de bibliotecas marcar determinados encabezados como externos. Un archivo que contiene #pragma system_header se considera externo desde el punto de la pragma hasta el final del archivo, como si se especificara como externo en la línea de comandos. El compilador emite todos los diagnósticos después de la pragma en el nivel de advertencia especificado por /external:Wn. Para obtener más información, consulte la pragma system_header.

Limitaciones

Algunas de las advertencias que emite la generación de código de back-end del compilador no se ven afectadas por las opciones /external. Estas advertencias suelen comenzar con C47XX, aunque no todas las advertencias C47XX son de back-end. Puede deshabilitar estas advertencias individualmente mediante /wd47XX. Las advertencias de análisis de código tampoco se ven afectadas, ya que no tienen niveles de advertencia.

Para establecer esta opción del compilador en el entorno de desarrollo de Visual Studio

En la versión 16.10 de Visual Studio 2019 y posteriores:

  1. Abra el cuadro de diálogo Páginas de propiedades del proyecto. Para más información, vea Establecimiento del compilador de C++ y de propiedades de compilación en Visual Studio.

  2. Seleccione la página de propiedades Propiedades de configuración>Directorios de VC++.

  3. Establezca la propiedad Directorios include externos para especificar el equivalente del IDE de la opción /external:I path para cada ruta de acceso delimitada por punto y coma.

  4. Seleccione la página de propiedades Propiedades de configuración>C/C++>Archivos incluidos como externos.

  5. Establezca las propiedades:

    • Establezca Tratar archivos incluidos con paréntesis angulares como externos en para establecer la opción /external:anglebrackets.

    • Nivel de advertencia de encabezado externo permite establecer la opción /external:Wn. Si este valor se establece en Heredar nivel de advertencia del proyecto o el valor predeterminado, se omiten otras opciones /external.

    • Establezca Diagnósticos de plantilla en encabezados externosen para establecer la opción /external:templates-.

  6. Haga clic en Aceptar o en Aplicar para guardar los cambios.

En versiones de Visual Studio anteriores a la versión 16.10 de Visual Studio 2019:

  1. Abra el cuadro de diálogo Páginas de propiedades del proyecto. Para más información, vea Establecimiento del compilador de C++ y de propiedades de compilación en Visual Studio.

  2. Seleccione la página de propiedades Propiedades de configuración>C/C++>Línea de comandos.

  3. Escriba la opción /experimental:external y otras opciones del compilador /external en el cuadro Opciones adicionales.

  4. Haga clic en Aceptar o en Aplicar para guardar los cambios.

Para establecer esta opción del compilador mediante programación

* Agregue la opción /experimental:external para habilitar las opciones de encabezados externos en las versiones de Visual Studio anteriores a la versión 16.10 de Visual Studio 2019.

Consulte también

Opciones del compilador de MSVC
Sintaxis de línea de comandos del compilador de MSVC