Skip to content

Commit 7c6c0cd

Browse files
TaojunshenTylerMSFTTylerMSFTColin Robertsonystamant
authored
8/3/2021 AM Publish (#3690)
* fix code sample (#3676) * fix code sample * acrolinx Co-authored-by: TylerMSFT <[email protected]> * Address 3269 typo in warning number (#3680) * Fixed typo: evalution --> evaluation * Bulk Fix - Sentence form for all alt text (#3683) * Updated C/C++ workload name The workload for C/C++ development in VS Build Tools 2019 installer is called 'Desktop development with C++'. * Split out docs by version Add VS2017-specific instructions. * Add 16.11 Compiler Warnings C5247 and C5248 (MicrosoftDocs#3689) * Add C5247 and C5248 * Fix link typos * Updates per Xiang Fan review * More wordsmithage * More fix per X.F. Co-authored-by: Tyler Whitney <[email protected]> Co-authored-by: TylerMSFT <[email protected]> Co-authored-by: Colin Robertson <[email protected]> Co-authored-by: ystamant <[email protected]> Co-authored-by: Andrew Shymanel <[email protected]>
1 parent 609d497 commit 7c6c0cd

File tree

7 files changed

+151
-16
lines changed

7 files changed

+151
-16
lines changed

docs/build/building-on-the-command-line.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: "Use the Microsoft C++ toolset from the command line"
33
description: "Use the Microsoft C++ (MSVC) compiler toolset from the command line outside of the Visual Studio IDE."
44
ms.custom: "conceptual"
5-
ms.date: "04/21/2020"
5+
ms.date: 08/02/2021
66
helpviewer_keywords: ["command-line builds [C++]", "compiling source code [C++], command line", "builds [C++], command-line", "command line [C++], building from", "command line [C++], compilers"]
77
ms.assetid: 7ca9daed-a003-4162-842d-908f79058365
88
---
@@ -15,7 +15,16 @@ You can build C and C++ applications on the command line by using tools that are
1515
1616
## Download and install the tools
1717

18-
If you've installed Visual Studio and a C++ workload, you have all the command-line tools. For information on how to install C++ and Visual Studio, see [Install C++ support in Visual Studio](vscpp-step-0-installation.md). If you only want the command-line toolset, download the [Build Tools for Visual Studio](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019). When you run the downloaded executable, it updates and runs the Visual Studio Installer. To install only the tools you need for C++ development, select the **C++ build tools** workload. You can select optional libraries and toolsets to include under **Installation details**. To build code by using the Visual Studio 2015 or 2017 toolsets, select the optional MSVC v140 or MSVC v141 build tools. When you're satisfied with your selections, choose **Install**.
18+
::: moniker range=">=msvc-160"
19+
20+
If you've installed Visual Studio and a C++ workload, you have all the command-line tools. For information on how to install C++ and Visual Studio, see [Install C++ support in Visual Studio](vscpp-step-0-installation.md). If you only want the command-line toolset, download the [Build Tools for Visual Studio](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019). When you run the downloaded executable, it updates and runs the Visual Studio Installer. To install only the tools you need for C++ development, select the **Desktop development with C++** workload. You can select optional libraries and toolsets to include under **Installation details**. To build code by using the Visual Studio 2015 or 2017 toolsets, select the optional MSVC v140 or MSVC v141 build tools. When you're satisfied with your selections, choose **Install**.
21+
22+
::: moniker-end
23+
::: moniker range="<=msvc-150"
24+
25+
If you've installed Visual Studio and a C++ workload, you have all the command-line tools. For information on how to install C++ and Visual Studio, see [Install C++ support in Visual Studio](vscpp-step-0-installation.md). If you only want the command-line toolset, download the [Build Tools for Visual Studio 2017](https://my.visualstudio.com/Downloads?q=2017). When you run the downloaded executable, it updates and runs the Visual Studio Installer. To install only the tools you need for C++ development, select the **Visual C++ build tools** workload. You can select optional libraries and toolsets to include under **Installation details**. To build code by using the Visual Studio 2015 toolset, select the optional MSVC v140 build tools. When you're satisfied with your selections, choose **Install**.
26+
27+
::: moniker-end
1928

2029
## How to use the command-line tools
2130

docs/c-runtime-library/crt-initialization.md

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22
title: "CRT Initialization"
33
description: "Describes how the CRT initializes global state in native code."
44
ms.topic: "conceptual"
5-
ms.date: "11/04/2016"
5+
ms.date: 08/02/2021
66
helpviewer_keywords: ["CRT initialization [C++]"]
77
ms.assetid: e7979813-1856-4848-9639-f29c86b74ad7
88
---
99
# CRT Initialization
1010

11-
This topic describes how the CRT initializes global state in native code.
11+
This article describes how the CRT initializes global state in native code.
1212

1313
By default, the linker includes the CRT library, which provides its own startup code. This startup code initializes the CRT library, calls global initializers, and then calls the user-provided `main` function for console applications.
1414

15+
It's possible, though not recommended, to take advantage of Microsoft-specific linker behavior to insert your own global initializers in a specific order. This code isn't portable, and comes with some important caveats.
16+
1517
## Initializing a Global Object
1618

1719
Consider the following code:
@@ -32,13 +34,13 @@ int main()
3234

3335
According to the C/C++ standard, `func()` must be called before `main()` is executed. But who calls it?
3436

35-
One way to determine the caller is to set a breakpoint in `func()`, debug the application, and examine the stack. This is possible because the CRT source code is included with Visual Studio.
37+
One way to determine the caller is to set a breakpoint in `func()`, debug the application, and examine the stack. It's possible because the CRT source code is included with Visual Studio.
3638

3739
When you browse the functions on the stack, you'll see that the CRT is calling a list of function pointers. These functions are similar to `func()`, or constructors for class instances.
3840

39-
The CRT gets the list of function pointers from the Microsoft C++ compiler. When the compiler sees a global initializer, it generates a dynamic initializer in the `.CRT$XCU` section where `CRT` is the section name and `XCU` is the group name. To get a list of dynamic initializers, run the command **dumpbin /all main.obj**, and then search the `.CRT$XCU` section. This applies when main.cpp is compiled as a C++ file, not a C file. It will be similar to the following example:
41+
The CRT gets the list of function pointers from the Microsoft C++ compiler. When the compiler sees a global initializer, it generates a dynamic initializer in the `.CRT$XCU` section where `CRT` is the section name and `XCU` is the group name. To get a list of dynamic initializers, run the command **`dumpbin /all main.obj`**, and then search the `.CRT$XCU` section. The command only applies when *`main.cpp`* is compiled as a C++ file, not a C file. It should be similar to this example:
4042

41-
```
43+
```cmd
4244
SECTION HEADER #6
4345
.CRT$XCU name
4446
0 physical address
@@ -72,11 +74,11 @@ The CRT defines two pointers:
7274

7375
Neither group has any other symbols defined except `__xc_a` and `__xc_z`.
7476

75-
Now, when the linker reads various `.CRT` groups, it combines them in one section and orders them alphabetically. This means that the user-defined global initializers (which the Microsoft C++ compiler puts in `.CRT$XCU`) will always come after `.CRT$XCA` and before `.CRT$XCZ`.
77+
Now, when the linker reads various `.CRT` subsections (the part after the `$`), it combines them in one section and orders them alphabetically. It means that the user-defined global initializers (which the Microsoft C++ compiler puts in `.CRT$XCU`) always come after `.CRT$XCA` and before `.CRT$XCZ`.
7678

77-
The section will resemble the following example:
79+
The section should resemble this example:
7880

79-
```
81+
```asm
8082
.CRT$XCA
8183
__xc_a
8284
.CRT$XCU
@@ -88,6 +90,26 @@ The section will resemble the following example:
8890

8991
So, the CRT library uses both `__xc_a` and `__xc_z` to determine the start and end of the global initializers list because of the way in which they're laid out in memory after the image is loaded.
9092

93+
## Linker features for initialization
94+
95+
The C++ Standard doesn't provide a conforming way to specify relative order across translation units for a user-supplied global initializer. However, since the Microsoft linker orders the `.CRT` subsections alphabetically, it's possible to take advantage of this ordering to specify initialization order. We don't recommend this Microsoft-specific technique, and it may break in a future release. We've documented it only to keep you from creating code that's broken in hard-to-diagnose ways.
96+
97+
To help prevent issues in your code, starting in Visual Studio 2019 version 16.11, we've added two new off by default warnings: [C5247](../error-messages/compiler-warnings/c5247.md) and [C5248](../error-messages/compiler-warnings/c5248.md). Enable these warnings to detect problems when creating your own initializers.
98+
99+
You can add initializers to unused reserved section names to create them in a specific relative order to the compiler generated dynamic initializers:
100+
101+
```cpp
102+
#pragma section(".CRT$XCT", read)
103+
// 'i1' is guaranteed to be called before any compiler generated C++ dynamic initializer
104+
__declspec(allocate(".CRT$XCT")) type i1 = f;
105+
106+
#pragma section(".CRT$XCV", read)
107+
// 'i2' is guaranteed to be called after any compiler generated C++ dynamic initializer
108+
__declspec(allocate(".CRT$XCV")) type i2 = f;
109+
```
110+
111+
The names `.CRT$XCT` and `.CRT$XCV` aren't used by either the compiler or the CRT library right now, but there's no guarantee that they'll remain unused in the future. And, your variables could still be optimized away by the compiler. Consider the potential engineering, maintenance, and portability issues before adopting this technique.
112+
91113
## See also
92114
93115
[C runtime (CRT) and C++ Standard Library (STL) `.lib` files](../c-runtime-library/crt-library-features.md)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: "Compiler Warning C5247"
3+
description: Compiler warning C5247 description and solution.
4+
ms.date: 08/02/2021
5+
f1_keywords: ["C5247"]
6+
helpviewer_keywords: ["C5247"]
7+
---
8+
# Compiler Warning C5247
9+
10+
> section '*section-name*' is reserved for C++ dynamic initialization. Manually creating the section will interfere with C++ dynamic initialization and may lead to undefined behavior
11+
12+
## Remarks
13+
14+
The Microsoft C++ compiler uses reserved section names for internal implementation of features such as C++ dynamic initialization. If your code creates a section with the same name as a reserved section, such as `.CRT$XCU`, it interferes with the compiler. It may prevent other dynamic initialization and cause undefined behavior.
15+
16+
To resolve this error, don't create a section that uses the reserved name.
17+
18+
There's no C++ standard conforming way to initialize variables across translation units, in a specific relative order with compiler generated dynamic initializers. Ways to force initialization before or after compiler generated C++ dynamic initializers are implementation-specific. For more information on Microsoft-specific implementation details, see [CRT initialization](../../c-runtime-library/crt-initialization.md).
19+
20+
Compiler Warning C5247 is new in Visual Studio 2019 version 16.11. It's off by default. For more information on how to enable this warning, see [Compiler warnings that are off by default](../../preprocessor/compiler-warnings-that-are-off-by-default.md).
21+
22+
## Example
23+
24+
Code that tries to emulate the C++ compiler behavior for dynamic initialization often takes this form:
25+
26+
```cpp
27+
void f();
28+
typedef void (*type)();
29+
30+
#pragma section(".CRT$XCU", read)
31+
__declspec(allocate(".CRT$XCU")) type i = f;
32+
```
33+
34+
This code creates a section using a reserved name, `.CRT$XCU`. It stops the compiler from creating the section with the expected properties, and it may skip other initializations. The variable `i` placed in the section is a regular variable, and isn't considered an initializer by the compiler. The compiler may optimize `i` away. The relative order when `f` gets called compared to other dynamic initializers is unspecified.
35+
36+
If initialization order isn't important, you can use this pattern to dynamically initialize a variable at startup:
37+
38+
```cpp
39+
void f();
40+
41+
struct init_helper {
42+
init_helper() { f(); }
43+
};
44+
45+
init_helper i;
46+
```
47+
48+
## See also
49+
50+
[CRT initialization](../../c-runtime-library/crt-initialization.md)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: "Compiler Warning C5248"
3+
description: Compiler warning C5248 description and solution.
4+
ms.date: 08/02/2021
5+
f1_keywords: ["C5248"]
6+
helpviewer_keywords: ["C5248"]
7+
---
8+
# Compiler Warning C5248
9+
10+
> section '*section-name*' is reserved for C++ dynamic initialization. Variables manually put into the section may be optimized out and their order relative to compiler generated dynamic initializers is unspecified
11+
12+
## Remarks
13+
14+
The Microsoft C++ compiler uses reserved section names for internal implementation of features such as C++ dynamic initialization. If your code inserts a variable in a reserved section, such as `.CRT$XCU`, it interferes with the compiler. Your variable isn't considered a C++ dynamic initializer. Also, its relative initialization order compared to compiler generated dynamic initializers isn't specified.
15+
16+
To resolve this error, don't create a section that uses the reserved name or insert a variable in the reserved section.
17+
18+
There's no C++ standard conforming way to initialize variables across translation units, in a specific relative order with compiler generated dynamic initializers. Ways to force initialization before or after compiler generated C++ dynamic initializers are implementation-specific. For more information on Microsoft-specific implementation details, see [CRT initialization](../../c-runtime-library/crt-initialization.md).
19+
20+
Compiler Warning C5248 is new in Visual Studio 2019 version 16.11. It's off by default. For more information on how to enable this warning, see [Compiler warnings that are off by default](../../preprocessor/compiler-warnings-that-are-off-by-default.md).
21+
22+
## Example
23+
24+
Code that tries to emulate the C++ compiler behavior for dynamic initialization often takes this form:
25+
26+
```cpp
27+
void f();
28+
typedef void (*type)();
29+
30+
#pragma section(".CRT$XCU", read)
31+
__declspec(allocate(".CRT$XCU")) type i = f;
32+
```
33+
34+
This code creates a section using a reserved name, `.CRT$XCU`. It stops the compiler from creating the section with the expected properties, and it may skip other initializations. The variable `i` placed in the section is a regular variable, and isn't considered an initializer by the compiler. The compiler may optimize `i` away. The relative order when `f` gets called compared to other dynamic initializers is unspecified.
35+
36+
If initialization order isn't important, you can use this pattern to dynamically initialize a variable at startup:
37+
38+
```cpp
39+
void f();
40+
41+
struct init_helper {
42+
init_helper() { f(); }
43+
};
44+
45+
init_helper i;
46+
```
47+
48+
## See also
49+
50+
[CRT initialization](../../c-runtime-library/crt-initialization.md)

0 commit comments

Comments
 (0)