/external(Внешние заголовки диагностика)

Параметры /external компилятора позволяют указать поведение диагностики компилятора для определенных файлов заголовков. Заголовки External — это естественное дополнение "Просто мой код": файлы заголовков, такие как системные файлы или сторонние файлы библиотеки, которые вы не можете или не намерены изменить. Так как вы не собираетесь изменять эти файлы, вы можете решить, что это не полезно для просмотра диагностических сообщений от компилятора о них. Параметры /external компилятора позволяют контролировать эти предупреждения.

Параметры /external компилятора доступны начиная с Visual Studio 2017 версии 15.6. В версиях Visual Studio до Visual Studio 2019 версии 16.10 /external параметры также требуют установки параметра компилятора /experimental:external .

Синтаксис

Используйте параметры внешнего заголовка (не требуется в версии 16.10 и более поздних версий):

/experimental:external

Укажите внешние заголовки:

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

Укажите поведение диагностика:

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

Аргументы

/experimental:external
Включает параметры внешних заголовков. Этот параметр не требуется в Visual Studio 2019 версии 16.10 и более поздних версий.

/external:anglebrackets
Обрабатывает все заголовки, включенные #include <header>в файл, где header файл заключен в угловые скобки (< >), как внешние заголовки.

/external:I path
Определяет корневой каталог, содержащий внешние заголовки. Все рекурсивные подкаталоги path считаются внешними, но только path значение добавляется в список каталогов, которые компилятор ищет включаемые файлы. Пространство между /external:I и path является необязательным. Каталоги, содержащие пробелы, должны быть заключены в двойные кавычки. Каталог может быть абсолютным путем или относительным путем.

/external:env:var
Указывает имя переменной var среды, содержащей разделенный точкой с запятой список внешних каталогов заголовков. Это полезно для систем сборки, использующих такие переменные среды, как INCLUDE, которые используются для указания списка внешних файлов включения. Кроме того, CAExcludePathдля файлов, которые не должны анализироваться /analyze. Например, можно указать /external:env:INCLUDE каждый каталог во INCLUDE внешнем каталоге заголовков одновременно. Это то же самое, что и для /external:I указания отдельных каталогов, но гораздо менее подробно. Между ними /external:env:не должно быть местаvar.

/external:Wn
Этот параметр задает уровень n предупреждения по умолчанию (значение от 0 до 4) для внешних заголовков. Например, /external:W0 эффективно отключает предупреждения для внешних заголовков. Если этот параметр не указан, компилятор выдает предупреждение командной строки D9007 для других /external параметров. Эти параметры игнорируются, потому что они не будут иметь никакого эффекта.

Параметр /external:Wn имеет эффект, аналогичный оболочке включенного заголовка в директиве #pragma warning :

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

/external:templates-
Разрешает предупреждения от внешних заголовков, когда они происходят в шаблоне, созданном в коде.

Замечания

По умолчанию уровень предупреждения, указанный /Wn для сборки, применяется ко всем файлам. Параметры для указания внешних заголовков определяют только набор файлов, к которым можно применить другой уровень предупреждения по умолчанию. Поэтому при указании внешних заголовков также используется /external:Wn для указания внешнего уровня предупреждения для изменения поведения компилятора.

Все существующие механизмы включения, отключения и подавления предупреждений по-прежнему работают как во внешних, так и не внешних файлах. Например, warning pragma может по-прежнему переопределить уровень предупреждения по умолчанию, заданный для внешних заголовков.

Пример. Установка внешнего уровня предупреждения

В этом примере программы есть два исходных файла и program.cpp header_file.h. Файл header_file.h находится в подкаталоге include_dir каталога, program.cpp содержащего файл:

Исходный файл 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
};

Исходный файл program.cpp:

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

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

Пример можно создать с помощью этой командной строки:

cl /EHsc /I include_dir /W4 program.cpp

Как ожидалось, этот пример создает предупреждение:

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

Для обработки файла заголовка как внешнего файла и подавления предупреждения можно* использовать эту командную строку:

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

Эта командная строка подавляет предупреждение внутри header_file.h при сохранении предупреждений внутри program.cpp.

Предупреждения через внутреннюю и внешнюю границу

Установка низкого уровня предупреждения для внешних заголовков может скрыть некоторые предупреждения, доступные для действий. В частности, он может отключить предупреждения, созданные для экземпляров шаблонов в пользовательском коде. Эти предупреждения могут указывать на проблему в коде, которая происходит только в экземплярах для определенных типов. (Например, если вы забыли применить признак типа, удаляющий const или &.) Чтобы избежать заглубления предупреждений внутри шаблонов, определенных во внешних заголовках, можно использовать этот /external:templates- параметр. Компилятор рассматривает как действующий уровень предупреждения в файле, который определяет шаблон, так и уровень предупреждения, на котором выполняется создание экземпляра шаблона. Предупреждения, создаваемые внутри внешнего шаблона, отображаются, если шаблон создается в не внешнем коде. Например, эта командная строка повторно включает предупреждения из источников шаблонов в примере кода*:

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

Предупреждение C4245 снова отображается в выходных данных, даже если код шаблона находится внутри внешнего заголовка.

Включение, отключение или отключение предупреждений

Все существующие механизмы включения, отключения и подавления предупреждений по-прежнему работают во внешних заголовках. Когда появится предупреждение, так как вы используете /external:templates- этот параметр, можно по-прежнему подавлять предупреждение в точке создания экземпляра. Например, чтобы явным образом отключить предупреждение в примере, который снова появится из-за /external:templates-директивы pragma, используйте следующую warning директиву:

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

Записи библиотек могут использовать одни и те же механизмы для применения определенных предупреждений или всех предупреждений на определенном уровне, если они чувствуют, что эти предупреждения никогда не должны быть замолчены /external:Wn. Например, эта версия файла заголовка выдает предупреждение C4245 об ошибке:

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

При этом изменении заголовка библиотеки автор библиотеки гарантирует, что глобальный уровень предупреждения в этом заголовке равен 4, независимо от того, что указано в /external:Wn. Теперь сообщаются все предупреждения уровня 4 и выше. Автор библиотеки также может заставить некоторые предупреждения быть ошибками, отключать, подавлять или выдаваться только один раз в заголовке. Параметры /external не переопределяют этот преднамеренный выбор.

pragma system_header

#pragma system_header — это навязчивый маркер, позволяющий записи библиотек пометить определенные заголовки как внешние. Файл, #pragma system_header содержащийся, считается внешним с точки pragma до конца файла, как если бы он был указан как внешний в командной строке. Компилятор выдает любой диагностика после pragma на уровне предупреждения, заданном ./external:Wn Дополнительные сведения см. в разделе system_header pragma.

Ограничения

Некоторые предупреждения, создаваемые внутренним кодом компилятора, не затрагиваются параметрами /external . Эти предупреждения обычно начинаются с C47XX, хотя не все предупреждения C47XX являются внутренними предупреждениями. Эти предупреждения по-прежнему можно отключить по отдельности с помощью /wd47XX. Предупреждения анализа кода также не влияют на них, так как они не имеют уровней предупреждений.

Установка данного параметра компилятора в среде разработки Visual Studio

В Visual Studio 2019 версии 16.10 и более поздних версиях:

  1. Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.

  2. Выберите страницу свойств>каталогов конфигурации VC++.

  3. Задайте свойство внешних каталогов включения, чтобы указать эквивалент интегрированной /external:I path среды разработки для каждого пути с запятой.

  4. Выберите страницу свойств>конфигурации C/C++>External Includes.

  5. Задайте свойства.

    • Задайте для параметра параметр "Задать файлы, включенные в угловые скобки как внешние" и "Да"./external:anglebrackets

    • Уровень предупреждения внешнего заголовка /external:Wn позволяет задать этот параметр. Если для этого значения задано значение "Наследовать уровень предупреждения проекта" или значение по умолчанию, другие /external параметры игнорируются.

    • Задайте для параметра "Диагностика шаблонов" в внешних заголовках значение "Да/external:templates-".

  6. Нажмите кнопку "ОК" или "Применить", чтобы сохранить изменения.

В версиях Visual Studio до Visual Studio 2019 версии 16.10:

  1. Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.

  2. Перейдите на страницу свойств Свойства конфигурации>C/C++>Командная строка.

  3. /experimental:external Введите параметр и другие /external параметры компилятора в поле "Дополнительные параметры".

  4. Нажмите кнопку "ОК" или "Применить", чтобы сохранить изменения.

Установка данного параметра компилятора программным способом

* Добавьте /experimental:external параметр включения параметров внешних заголовков в версиях Visual Studio до Visual Studio 2019 версии 16.10.

См. также

Параметры компилятора MSVC
Синтаксис командной строки компилятора MSVC