Skip to content

Commit 89a6c33

Browse files
author
Colin Robertson
authored
Merge pull request MicrosoftDocs#3137 from MicrosoftDocs/master637566105365374553
Repo sync for protected CLA branch
2 parents e4004d6 + 3163c67 commit 89a6c33

File tree

4 files changed

+180
-0
lines changed

4 files changed

+180
-0
lines changed

docs/build/reference/compiler-options-listed-alphabetically.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ This table contains an alphabetical list of compiler options. For a list of comp
3232
| [`/EP`](ep-preprocess-to-stdout-without-hash-line-directives.md) | Copies preprocessor output to standard output. |
3333
| [`/errorReport`](errorreport-report-internal-compiler-errors.md) | Deprecated. Error reporting is controlled by [Windows Error Reporting (WER)](/windows/win32/wer/windows-error-reporting) settings. |
3434
| [`/execution-charset`](execution-charset-set-execution-character-set.md) | Set the execution character set. |
35+
| [`/experimental:external`](external-external-headers-diagnostics.md) | Enables experimental external headers support. |
3536
| [`/experimental:module`](experimental-module.md) | Enables experimental module support. |
3637
| [`/experimental:preprocessor`](experimental-preprocessor.md) | Deprecated. Enables experimental conforming preprocessor support. Use [`/Zc:preprocessor`](zc-preprocessor.md) |
3738
| [`/exportHeader`](module-exportheader.md) | Create the header units (*`.ifc`*) files specified by the input arguments. |
39+
| [`/external`](external-external-headers-diagnostics.md) | Allows control of diagnostics in external headers. |
3840
| [`/F`](f-set-stack-size.md) | Sets stack size. |
3941
| [`/favor`](favor-optimize-for-architecture-specifics.md) | Produces code optimized for a specific x64 architecture. Or, for the specific micro-architectures in both the AMD64 and EM64T architectures. |
4042
| [`/FA`](fa-fa-listing-file.md) | Creates a listing file. |

docs/build/reference/compiler-options-listed-by-category.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ This article contains a categorical list of compiler options. For an alphabetica
165165
| [`/c`](c-compile-without-linking.md) | Compiles without linking. |
166166
| [`/cgthreads`](cgthreads-code-generation-threads.md) | Specifies number of *cl.exe* threads to use for optimization and code generation. |
167167
| [`/errorReport`](errorreport-report-internal-compiler-errors.md) | Deprecated. Error reporting is controlled by [Windows Error Reporting (WER)](/windows/win32/wer/windows-error-reporting) settings. |
168+
| [`/external`](external-external-headers-diagnostics.md) | Allows control of diagnostics in external headers. |
168169
| [`/FC`](fc-full-path-of-source-code-file-in-diagnostics.md) | Displays the full path of source code files passed to *cl.exe* in diagnostic text. |
169170
| [`/FS`](fs-force-synchronous-pdb-writes.md) | Forces writes to the PDB file to be serialized through *MSPDBSRV.EXE*. |
170171
| [`/fsanitize`](fsanitize.md) | Enables compilation of sanitizer instrumentation such as AddressSanitizer. |
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
---
2+
title: "/external (External headers diagnostics)"
3+
description: "The Microsoft C++ compiler /external headers diagnostic options syntax and usage."
4+
ms.date: 05/14/2021
5+
f1_keywords: ["/external", "/external:anglebrackets", "/external:env:", "/external:I", "/external:W0", "/external:W1", "/external:W2", "/external:W3", "/external:W4", "/external:templates-", "/experimental:external"]
6+
helpviewer_keywords: ["/external compiler option [C++]", "-external compiler option [C++]", "external compiler option [C++]"]
7+
---
8+
# `/external` (External headers diagnostics)
9+
10+
The **`/external`** compiler options let you specify compiler diagnostic behavior for certain header files. "External" headers are the natural complement of "Just my code": Header files such as system files or third-party library files that you can't or don't intend to change. Since you aren't going to change these files, you may decide it isn't useful to see diagnostic messages from the compiler about them. The `/external` compiler options give you control over these warnings.
11+
12+
The **`/external`** compiler options are available starting in Visual Studio 2017 version 15.6. The **`/external`** options require you also set the **`/experimental:external`** compiler option.
13+
14+
## Syntax
15+
16+
Use external header options:
17+
> **`/experimental:external`**
18+
19+
Specify external headers:
20+
> **`/external:anglebrackets`**\
21+
> **`/external:env:`**_`var`_\
22+
> **`/external:I`** *`path`*
23+
24+
Specify diagnostics behavior:
25+
> **`/external:W`**_`n`_\
26+
> **`/external:templates-`**
27+
28+
### Arguments
29+
30+
**`/experimental:external`**\
31+
Enables the external headers options, starting in Visual Studio 2017 version 15.6.
32+
33+
**`/external:anglebrackets`**\
34+
Treats all headers included by `#include <header>`, where the *`header`* file is enclosed in angle brackets (**`< >`**), as external headers.
35+
36+
**`/external:I`** *`path`*\
37+
Defines a root directory that contains external headers. All recursive subdirectories of *`path`* are considered external, but only the *`path`* value is added to the list of directories the compiler searches for include files. The space between **`/external:I`** and *`path`* is optional. Directories that include spaces must be enclosed in double quotes. A directory may be an absolute path or a relative path.
38+
39+
**`/external:env:`**_`var`_\
40+
Specifies the name of an environment variable *`var`* that holds a semicolon-separated list of external header directories. It's useful for build systems that rely on environment variables such as `INCLUDE`, which you use to specify the list of external include files. Or, `CAExcludePath`, for files that shouldn't be analyzed by `/analyze`. For example, you can specify `/external:env:INCLUDE` to make every directory in `INCLUDE` an external header directory at once. It's the same as using **`/external:I`** to specify the individual directories, but much less verbose. There should be no space between *`var`* and **`/external:env:`**.
41+
42+
**`/external:Wn`**\
43+
This option sets the default warning level to *`n`* (a value from 0 to 4) for external headers. For example, **`/external:W0`** effectively turns off warnings for external headers. The **`/external:Wn`** option has an effect similar to wrapping an included header in a `#pragma warning` directive:
44+
45+
```cpp
46+
#pragma warning (push, 0)
47+
// the global warning level is now 0 here
48+
#include <external_header>
49+
#pragma warning (pop)
50+
```
51+
52+
**`/external:templates-`**\
53+
Allows warnings from external headers when they occur in a template that's instantiated in your code.
54+
55+
## Remarks
56+
57+
By default, the **`/Wn`** warning level you specify for your build applies to all files. The options to specify external headers only define a set of files to which you can apply a different default warning level. So, if you specify external headers, also use **`/external:Wn`** to specify an external warning level to change compiler behavior.
58+
59+
All the existing mechanisms to enable, disable, and suppress warnings still work in both external and non-external files. For example, a [`warning` pragma](../../preprocessor/warning.md) can still override the default warning level you set for external headers.
60+
61+
### Example: Set external warning level
62+
63+
This sample program has two source files, *`program.cpp`* and *`header_file.h`*. The *`header_file.h`* file is in an *`include_dir`* subdirectory of the directory containing the *`program.cpp`* file:
64+
65+
```cpp
66+
// External header: include_dir/header_file.h
67+
68+
template <typename T>
69+
struct sample_struct
70+
{
71+
static const T value = -7; // W4: warning C4245: 'initializing':
72+
// conversion from 'int' to 'unsigned int', signed/unsigned mismatch
73+
};
74+
```
75+
76+
```cpp
77+
// User code: program.cpp
78+
#include <header_file.h>
79+
80+
int main()
81+
{
82+
return sample_struct<unsigned int>().value;
83+
}
84+
```
85+
86+
You can build the sample by using this command line:
87+
88+
```cmd
89+
cl /EHsc /I include_dir /W4 program.cpp
90+
```
91+
92+
As expected, this sample generates a warning:
93+
94+
```console
95+
program.cpp
96+
include_dir\header_file.h(6): warning C4245: 'initializing': conversion from 'int' to 'const T', signed/unsigned mismatch
97+
with
98+
[
99+
T=unsigned int
100+
]
101+
program.cpp(6): note: see reference to class template instantiation 'sample_struct<unsigned int>' being compiled
102+
```
103+
104+
To treat the header file as an external file and suppress the warning, you can use this command line instead:
105+
106+
```cmd
107+
cl /EHsc /experimental:external /I include_dir /external:anglebrackets /external:W0 /W4 program.cpp
108+
```
109+
110+
This command line suppresses the warning inside *`header_file.h`* while preserving warnings inside *`program.cpp`*.
111+
112+
### Warnings across the internal and external boundary
113+
114+
Setting a low warning level for external headers can hide some actionable warnings. In particular, it can turn off warnings emitted on template instantiations in user code. These warnings might indicate a problem in your code that only happens in instantiations for particular types. (For example, if you forgot to apply a type trait removing `const` or `&`.) To avoid silencing warnings inside templates defined in external headers, you can use the **`/external:templates-`** option. The compiler considers both the effective warning level in the file that defines the template, and the warning level where template instantiation occurs. Warnings emitted inside an external template appear if the template is instantiated within non-external code. For example, this command line re-enables warnings from template sources in the sample code:
115+
116+
```cmd
117+
cl /EHsc /experimental:external /I include_dir /external:anglebrackets /external:W0 /external:templates- /W4 program.cpp
118+
```
119+
120+
The C4245 warning appears again in the output, even though the template code is inside an external header.
121+
122+
### Enable, disable, or suppress warnings
123+
124+
All the existing mechanisms to enable, disable, and suppress warnings still work in external headers. When a warning appears because you use the **`/external:templates-`** option, you can still suppress the warning at the point of instantiation. For example, to explicitly suppress the warning in the sample that reappears because of **`/external:templates-`**, use a `warning` pragma directive:
125+
126+
```cpp
127+
int main()
128+
{
129+
#pragma warning( suppress : 4245)
130+
return sample_struct<unsigned int>().value;
131+
}
132+
```
133+
134+
Library writers can use the same mechanisms to enforce certain warnings, or all the warnings at certain level, if they feel those warnings should never be silenced by **`/external:Wn`**. For example, this version of the header file forces warning C4245 to report an error:
135+
136+
```cpp
137+
// External header: include_dir/header_file.h
138+
139+
#pragma warning( push, 4 )
140+
#pragma warning( error : 4245 )
141+
142+
template <typename T>
143+
struct sample_struct
144+
{
145+
static const T value = -7; // W4: warning C4245: 'initializing': conversion from 'int'
146+
// to 'unsigned int', signed/unsigned mismatch
147+
};
148+
149+
#pragma warning( pop )
150+
```
151+
152+
With this change to the library header, the author of the library ensures that the global warning level in this header is 4, no matter what gets specified in **`/external:Wn`**. Now all level 4 and above warnings are reported. The library author can also force certain warnings to be errors, disabled, suppressed, or emitted only once in the header. The **`/external`** options don't override that deliberate choice.
153+
154+
`#pragma system_header` is an intrusive header marker that allows library writers to mark certain headers as external. These headers have the warning level specified by **`/external:Wn`**, if any.
155+
156+
### Limitations
157+
158+
Some warnings emitted by the compiler's back-end code generation aren't affected by the **`/external`** options. These warnings usually start with C47XX, though not all C47XX warnings are back-end warnings. You can still disable these warnings by using `/wd47XX`. Code analysis warnings are also unaffected, since they don't have warning levels.
159+
160+
### To set this compiler option in the Visual Studio development environment
161+
162+
1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
163+
164+
1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.
165+
166+
1. Enter the compiler options in the **Additional Options** box.
167+
168+
### To set this compiler option programmatically
169+
170+
- See <xref:Microsoft.VisualStudio.VCProjectEngine.VCCLCompilerTool.AdditionalOptions%2A>.
171+
172+
## See also
173+
174+
[MSVC compiler options](compiler-options.md)\
175+
[MSVC compiler command-line syntax](compiler-command-line-syntax.md)

docs/build/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,8 @@
519519
href: ../build/reference/experimental-module.md
520520
- name: /experimental:preprocessor
521521
href: ../build/reference/experimental-preprocessor.md
522+
- name: /external (External headers diagnostics)
523+
href: ../build/reference/external-external-headers-diagnostics.md
522524
- name: /F (Set stack size)
523525
href: ../build/reference/f-set-stack-size.md
524526
- name: Output-file (/F) options

0 commit comments

Comments
 (0)