Skip to content

Commit 46b3f2f

Browse files
Merge pull request #5047 from MicrosoftDocs/main638530327163594523sync_temp
For protected branch, push strategy should use PR and merge to target branch method to work around git push error
2 parents a97cc18 + e5b28bc commit 46b3f2f

File tree

1 file changed

+149
-2
lines changed

1 file changed

+149
-2
lines changed

docs/overview/cpp-conformance-improvements.md

Lines changed: 149 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "C++ conformance improvements in Visual Studio 2022"
33
description: "Microsoft C++ in Visual Studio is improving standards conformance and fixing bugs regularly."
4-
ms.date: 02/20/2024
4+
ms.date: 05/31/2024
55
ms.service: "visual-cpp"
66
ms.subservice: "cpp-lang"
77
---
@@ -15,6 +15,153 @@ For changes in Visual Studio 2019, see [C++ conformance improvements in Visual S
1515
For changes in Visual Studio 2017, see [C++ conformance improvements in Visual Studio 2017](cpp-conformance-improvements-2017.md).\
1616
For changes in older versions, see [Visual C++ What's New 2003 through 2015](../porting/visual-cpp-what-s-new-2003-through-2015.md).
1717

18+
## <a name="improvements_1710"></a> Conformance improvements in Visual Studio 2022 version 17.10
19+
20+
Visual Studio 2022 version 17.10 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
21+
22+
For an in-depth summary of changes made to the Standard Template Library, including conformance changes, bug fixes and performance improvements, see [STL Changelog VS 2022 17.10](https://github.com/microsoft/STL/wiki/Changelog#vs-2022-1710).
23+
24+
### Conversion operator specialization with explicitly specified return type
25+
26+
The compiler used to specialize conversion operators incorrectly in some cases which could lead to a mismatched return type. These invalid specializations no longer happen. This is a source code breaking change.
27+
28+
```cpp
29+
// Example 1
30+
struct S
31+
{
32+
template<typename T> operator const T*();
33+
};
34+
35+
void test()
36+
{
37+
S{}.operator int*(); // this is invalid now
38+
S{}.operator const int*(); // this is valid
39+
}
40+
```
41+
42+
```cpp
43+
// Example 2
44+
// In some cases, the overload resolution result may change
45+
struct S
46+
{
47+
template <typename T> operator T*(); // overload 1
48+
template <typename T> operator const T*(); // overload 2
49+
};
50+
51+
void test()
52+
{
53+
S{}.operator int*(); // this used to call overload 2, now it calls overload 1
54+
}
55+
```
56+
57+
### Added Support for `#elifdef` and `#elifndef`
58+
59+
Support added for WG21 [P2334R1](https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2021/p2334r1.pdf) (C++23) and WG14 [N2645](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2645.pdf) (C++23) which introduced the `#elifdef` and `#elifndef` preprocessor directives.
60+
Requires `/std:clatest` or `/std:c++latest`.
61+
62+
Before:
63+
64+
```cpp
65+
#ifdef __cplusplus
66+
#include <atomic>
67+
#elif !defined(__STDC_NO_ATOMICS__)
68+
#include <stdatomic.h>
69+
#else
70+
#include <custom_atomics_library.h>
71+
#endif
72+
```
73+
74+
After:
75+
76+
```cpp
77+
#ifdef __cplusplus
78+
#include <atomic>
79+
#elifndef __STDC_NO_ATOMICS__
80+
#include <stdatomic.h>
81+
#else
82+
#include <custom_atomics_library.h>
83+
#endif
84+
```
85+
86+
### Application of `_Alignas` on a structured type in C
87+
88+
Applies to the C language (C17 and later). Also added to Microsoft Visual Studio 17.9
89+
90+
In versions of Visual C++ before Visual Studio 2022 version 17.9, if the `_Alignas` specifier appeared adjacent to a structured type in a declaration, it wasn't applied correctly according to the ISO-C Standard.
91+
92+
```cpp
93+
// compile with /std:c17
94+
#include <stddef.h>
95+
96+
struct Outer
97+
{
98+
_Alignas(32) struct Inner { int i; } member1;
99+
struct Inner member2;
100+
};
101+
static_assert(offsetof(struct Outer, member2)==4, "incorrect alignment");
102+
```
103+
104+
According to the ISO-C Standard, this code should compile without `static_assert` emitting a diagnostic.
105+
106+
The `_Alignas` directive applies only to the member variable `member1`. It must not change the alignment of `struct Inner`. However, before Visual Studio 17.9.1, the diagnostic "incorrect alignment" was emitted. The compiler aligned `member2` to an offset of 32 bytes within the `struct Outer` type.
107+
108+
This is a binary breaking change, so a warning is now emitted when this change takes effect. Warning C5274 is now emitted at warning level 1 for the previous example: `
109+
warning C5274: behavior change: _Alignas no longer applies to the type 'Inner' (only applies to declared data objects)`.
110+
111+
Also, in previous versions of Visual Studio, when the `_Alignas` specifier appeared adjacent to an anonymous type declaration, it was ignored.
112+
113+
```cpp
114+
// compile with /std:c17
115+
#include <stddef.h>
116+
struct S
117+
{
118+
_Alignas(32) struct { int anon_member; };
119+
int k;
120+
};
121+
122+
static_assert(offsetof(struct S, k)==4, "incorrect offsetof");
123+
static_assert(sizeof(struct S)==32, "incorrect size");
124+
```
125+
126+
Previously, both `static_assert` statements failed when compiling this code. Now the code compiles, but emits the following level 1 warnings:
127+
128+
```c
129+
warning C5274: behavior change: _Alignas no longer applies to the type '<unnamed-tag>' (only applies to declared data objects)
130+
warning C5273: behavior change: _Alignas on anonymous type no longer ignored (promoted members will align)
131+
```
132+
133+
To get the previous behavior, replace `_Alignas(N)` with `__declspec(align(N))`. Unlike `_Alignas`, `declspec(align)` applies to the type.
134+
135+
### Improved warning C4706
136+
137+
This is a source code breaking change. Previously, the compiler didn't detect the convention of wrapping an assignment in parentheses, if assignment was intended, to suppress [warning C4706](../error-messages/compiler-warnings/compiler-warning-level-4-c4706.md) about assignment within a conditional expression. The compiler now detects the parentheses and suppresses the warning.
138+
139+
```cpp
140+
#pragma warning(error: 4706)
141+
142+
struct S
143+
{
144+
auto mf()
145+
{
146+
if (value = 9)
147+
return value + 4;
148+
else
149+
return value;
150+
}
151+
152+
int value = 9;
153+
};
154+
```
155+
156+
The compiler now also emits the warning in cases where the function isn't referenced. Previously, because `mf` is an inline function that isn't referenced, warning C4706 wasn't emitted for this code. Now the warning is emitted:
157+
158+
```cpp
159+
error C4706: assignment used as a condition
160+
note: if an assignment is intended you can enclose it in parentheses, '(e1 = e2)', to silence this warning
161+
```
162+
163+
To fix this warning, either use an equality operator, `value == 9`, if this is what was intended. Or, wrap the assignment in parentheses, `(value = 9)`, if assignment is intended. Otherwise, since the function is unreferenced, remove it.
164+
18165
## <a name="improvements_179"></a> Conformance improvements in Visual Studio 2022 version 17.9
19166

20167
Visual Studio 2022 version 17.9 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
@@ -566,7 +713,7 @@ int main(void)
566713
567714
In Visual Studio 2022 version 17.1 and later, if the expression associated with a `static_assert` isn't a dependent expression, the compiler evaluates the expression when it's parsed. If the expression evaluates to `false`, the compiler emits an error. Previously, if the `static_assert` was within the body of a function template (or within the body of a member function of a class template), the compiler wouldn't perform this analysis.
568715
569-
This change is a source breaking change. It applies in any mode that implies **`/permissive-`** or **`/Zc:static_assert`**. This change in behavior can be disabled by using the **`/Zc:static_assert-`** compiler option.
716+
This change is a source breaking change. It applies in any mode that implies **`/permissive-`** or **`/Zc:static_assert`**. This change in behavior can be disabled by using the **`/Zc:static_assert-`** compiler option.
570717
571718
#### Example
572719

0 commit comments

Comments
 (0)