You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/overview/cpp-conformance-improvements.md
+98-45Lines changed: 98 additions & 45 deletions
Original file line number
Diff line number
Diff line change
@@ -19,14 +19,13 @@ For changes in older versions, see [Visual C++ What's New 2003 through 2015](../
19
19
20
20
Visual Studio 2022 version 17.10 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.
21
21
22
-
For a broader summary of changes made to the Standard Template Library, see [STL Changelog VS 2022 17.10](https://github.com/microsoft/STL/wiki/Changelog#vs-2022-1710).
22
+
For an in-depth summary of changes made to the Standard Template Library, including bug fixes and performance improvements, see [STL Changelog VS 2022 17.10](https://github.com/microsoft/STL/wiki/Changelog#vs-2022-1710).
23
23
24
24
---------------------- TW
25
-
### Conversion operator specialization with explicitly specified return type
26
25
27
-
This is a source code breaking change. The compiler used to specialize these conversion operators incorrectly in some cases which can lead to mismatched return type. These invalid specializations no longer happen.
26
+
### Conversion operator specialization with explicitly specified return type
28
27
29
-
#### Example (before/after)
28
+
The compiler used to specialize conversion operators incorrectly in some cases which can lead to mismatched return type. These invalid specializations no longer happen. This is a source code breaking change.
| Yes | C (C17 and later) | No | Unchanged | fe_20231031.02|
90
+
Applies to the C language (C17 and later). Also added to Microsoft Visual Studio 17.9
96
91
97
-
### Description/Rationale
98
-
In versions of Visual C++ before Visual Studio 2022 version 17.9, when the `_Alignas` specifier appeared adjacent to a structured type in a declaration, it was not applied correctly according to the ISO-C Standard.
92
+
In versions of Visual C++ before Visual Studio 2022 version 17.9, when the `_Alignas` specifier appeared adjacent to a structured type in a declaration, it wasn't applied correctly according to the ISO-C Standard.
According to the ISO-C Standard, this code should compile without the 'static_assert' emitting a diagnostic. The '_Alignas' directive applies only to the member variable 'member1'. It must not change the alignment of 'struct Inner'. However, before release 17.9.1 of Visual Studio, the diagnostic "incorrect alignment" would be emitted. The compiler would align 'member2' to an offset of 32 bytes within the 'struct Outer' type.
106
+
According to the ISO-C Standard, this code should compile without `static_assert` emitting a diagnostic.
112
107
113
-
Since fixing this bug is a binary breaking change, a warning is now emitted when this change takes effect. Warning C5274 is now emitted at warning level 1 for the code above:
114
-
```
108
+
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.
109
+
110
+
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 code:
111
+
112
+
```cpp
115
113
warning C5274: behavior change: _Alignas no longer applies to the type 'Inner' (only applies to declared data objects)
116
114
```
117
-
A second fix was made to _Alignof in this release. In previous versions of Visual Studio, when the _Alignas specifier appeared adjacent to an anonymous type declaration, it was ignored.
118
-
###Example
119
-
```
115
+
116
+
Also, in previous versions of Visual Studio, when the `_Alignas` specifier appeared adjacent to an anonymous type declaration, it was ignored.
Previously, both `static_assert` statements would fail when this code was compiled. Now the code will compile, but with the following level 1 warnings emitted:
130
-
```
130
+
131
+
Previously, both `static_assert` statements failed when compiling this code. Now the code compiles, but emits the following level 1 warnings:
132
+
133
+
```cpp
131
134
warning C5274: behavior change: _Alignas no longer applies to the type '<unnamed-tag>' (only applies to declared data objects)
132
135
warning C5273: behavior change: _Alignas on anonymous type no longer ignored (promoted members will align)
133
136
```
134
-
The previous behavior can be achieved by replacing uses of `_Alignas(N)` with `__declspec(align(N))`. This declspec is a documented feature of Visual C and C++ for many releases. Unlike `_Alignas`, use of `declspec(align)` will apply to the type.
To get the previous behavior, replace `_Alignas(N)` with `__declspec(align(N))`. Unlike `_Alignas`, `declspec(align)` applies to the type.
144
139
145
-
Previously this warning was emitted by the optimizer, c2.dll: one side-effect of this was that the compiler could not detect the convention for suppressing the warning: i.e., wrapping the assignment in parentheses (if an assignment really was intended). By moving the warning from the optimizer to the parser, c1.dll or c1xx.dll, the compiler can now detect the parentheses and hence suppress the warning in these cases.
140
+
### Improved warning C4706
146
141
147
-
When the warning was in the optimizer it would only check functions that were, in some way, referenced and hence passed to the optimizer to process. If a function was not referenced, then the optimizer would never see it and the warning would not be emitted.
142
+
This is a source code breaking change. Previously, the compiler didn't detect the convention for suppressing the warning. That is, wrapping the assignment in parentheses (if an assignment really was intended). The compiler now detects the parentheses and suppresses the warning.
148
143
149
-
Now that the warning is in the parser it will be emitted for all functions regardless of whether they are referenced or not.
144
+
The compiler now also emits the warning in cases where the function isn't referenced.
150
145
151
-
### Example
152
-
```
146
+
```cpp
147
+
// example
153
148
#pragma warning(error: 4706)
154
149
155
-
struct S {
156
-
auto mf() {
150
+
structS
151
+
{
152
+
auto mf()
153
+
{
157
154
if (value = 9)
158
155
return value + 4;
159
156
else
@@ -163,13 +160,69 @@ struct S {
163
160
int value = 9;
164
161
};
165
162
```
166
-
Previously, as 'mf' is an inline function that is never referenced, it would not be passed to the optimizer and hence warning C4706 would not be emitted for this code: but now that the parser is being used to detect this situation the warning is emitted.
167
-
```
163
+
164
+
Previously, because `mf` is an inline function that isn't referenced, warning C4706 wasn't emitted for this code. Now the warning is emitted:
165
+
166
+
```cpp
168
167
t.cpp(5): error C4706: assignment used as a condition
169
168
t.cpp(5): note: if an assignment is intended you can enclose it in parentheses, '(e1 = e2)', to silence this warning
170
169
```
171
-
The fix is to either switch to an equality operator, 'value == 9', if this is what was intended, or to wrap the assignment in parentheses, '(value = 9)', if an assignment really was intended. Or, as the function is unreferenced, it can be removed.
172
170
171
+
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 what is intended. Or, since the function is unreferenced, remove it.
172
+
173
+
---------------------- end /TW for compiler conformance. START FOR STL
174
+
### C++ Standard Library
175
+
176
+
**LWG issue resolutions**
177
+
178
+
[LWG-3749](https://wg21.link/lwg3749)`common_iterator` should handle integer-class difference types. Previously, given:
179
+
```cpp
180
+
template<input_iterator I, class S>
181
+
struct iterator_traits<common_iterator<I, S>>
182
+
{
183
+
using iterator_concept = see below;
184
+
using iterator_category = see below;
185
+
using value_type = iter_value_t<I>;
186
+
using difference_type = iter_difference_t<I>;
187
+
using pointer = see below;
188
+
using reference = iter_reference_t<I>;
189
+
};
190
+
```
191
+
192
+
Where `difference_type` is defined as `iter_difference_t<I>` and `iterator_category` is defined as at least `input_iterator_tag`. However, when `difference_type` is an integer-class type, `common_iterator` didn't satisfy `Cpp17InputIterator`, defining `iterator_category` incorrectly as `input_iterator_tag`. This issue is resolved by defining `difference_type` as `ptrdiff_t` when `iter_difference_t<I>` is an integer-class type.
193
+
194
+
[LWG-3809](https://wg21.link/lwg3809)`subtract_with_carry_engine<uint16_t>` now works. Previously, `subtract_with_carry_engine<uint16_t>` didn't work because the `subtract_with_carry_engine` template was specialized for `uint32_t` and `uint64_t` only. This issue is resolved by adding a specialization for `uint16_t`.
195
+
196
+
[LWG-3897](https://wg21.link/lwg3897)`inout_ptr` will not update raw pointer to null. Previously, the `std::inout_ptr_t` destructor didn't update a raw pointer to be `null`, but now it does. This change ensures that the raw pointer is correctly set to `nullptr` when the `std::inout_ptr_t` object goes out of scope.
197
+
198
+
LWG-3946 #4187 The definition of const_iterator_t should be reworked
199
+
200
+
**C++20 changes**
201
+
202
+
- Defect report [P2905R2](https://wg21.link/P2905R2) Runtime Format Strings. Now `make_format_args` takes lvalue references instead of forwarding references, which means the following problematic code no longer compiles:
auto args = std::make_format_args(path.string()); // undefined behavior because format arguments store a reference to a temporary that is destroyed before use.
206
+
```
207
+
- [P2909R4](https://wg21.link/P2909R4) Fix Formatting Of Code Units As Integers. When `std::format` formats `char` as an integer via `d` and `x`, it now takes the signedness of char into account. This is a breaking change that only affects the output of negative/large code units when output via opt-in format specifiers. The output is no longer implementation-defined making code porting more reliable. For example:
208
+
```cpp
209
+
for (char c : std::string("🤷"))
210
+
{
211
+
std::print("\\x{:02x}", c);
212
+
}
213
+
```
214
+
215
+
This code would output `\xf0\x9f\xa4\xb7` or `\x-10\x-61\x-5c\x-49` depending on platform. Now ...
216
+
217
+
**C++23 changes**
218
+
219
+
-[P2836R1](https://wg21.link/P2836R1)`basic_const_iterator` should follow its underlying type's convertibility. Now `basic_const_iterator<I>` is implicitly convertible to any constant iterator that `I` can be implicitly and explicitly convertible to.
-[P2510R3](https://wg21.link/P2510R3) Formatting Pointers: The number of formatting options for pointer types is limited when compared to integer types. This change makes formatting pointer types more useful, reducing the need for to write your own formatters or cast a pointer type to an integer type.
225
+
-[P2937R0](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2937r0.html) Remove `strtok` from the freestanding library. It is still available in the hosted environment.
173
226
---------------------- /TW
174
227
175
228
## <aname="improvements_179"></a> Conformance improvements in Visual Studio 2022 version 17.9
0 commit comments