Skip to content

Repo sync for protected CLA branch #4595

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ The compiler doesn't support most optional features of ISO C11. Several of these

- `aligned_alloc` support is missing, because of the Windows heap implementation. The alternative is to use [`_aligned_malloc`](../../c-runtime-library/reference/aligned-malloc.md).

- [DR 400](https://wg14.link/n2148#dr_400) support is currently unimplemented for `realloc`, because this change would break the ABI.
- [Defect report 400](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2148.htm#dr_400) support is currently unimplemented for `realloc` because this change would break the ABI.

- Variable length array (VLA) support isn't planned. VLAs provide attack vectors comparable to [`gets`](../../c-runtime-library/gets-getws.md), which is deprecated and planned for removal.

Expand Down
90 changes: 82 additions & 8 deletions docs/overview/cpp-conformance-improvements.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,88 @@
---
title: "C++ conformance improvements in Visual Studio 2022"
description: "Microsoft C++ in Visual Studio is improving standards conformance and fixing bugs regularly."
ms.date: 03/01/2023
ms.date: 06/19/2023
ms.technology: "cpp-language"
---
# C++ Conformance improvements, behavior changes, and bug fixes in Visual Studio 2022

Microsoft C/C++ in Visual Studio (MSVC) makes conformance improvements and bug fixes in every release. This article lists the significant improvements by major release, then by version. To jump directly to the changes for a specific version, use the list below **In this article**.
Microsoft C/C++ in Visual Studio (MSVC) makes conformance improvements and bug fixes in every release. This article lists the significant improvements by major release, then by version. To jump directly to the changes for a specific version, use **In this article** links, above.

This document lists the changes in Visual Studio 2022. For a guide to the changes in Visual Studio 2019, see [C++ conformance improvements in Visual Studio 2019](cpp-conformance-improvements-2019.md). For changes in Visual Studio 2017, see [C++ conformance improvements in Visual Studio 2017](cpp-conformance-improvements-2017.md). For a complete list of previous conformance improvements, see [Visual C++ What's New 2003 through 2015](../porting/visual-cpp-what-s-new-2003-through-2015.md).
This document lists the changes in Visual Studio 2022:

- For a guide to the changes in Visual Studio 2019, see [C++ conformance improvements in Visual Studio 2019](cpp-conformance-improvements-2019.md).
- For changes in Visual Studio 2017, see [C++ conformance improvements in Visual Studio 2017](cpp-conformance-improvements-2017.md).
- For a complete list of previous conformance improvements, see [Visual C++ What's New 2003 through 2015](../porting/visual-cpp-what-s-new-2003-through-2015.md).

## <a name="improvements_176"></a> Conformance improvements in Visual Studio 2022 version 17.6

Visual Studio 2022 version 17.6 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.

### Compound `volatile` assignments no longer deprecated

C++20 deprecated applying certain operators to types qualified with `volatile`. For example, when the following code is compiled with `cl /std:c++20 /Wall test.cpp`:

```cpp
void f(volatile int& expr)
{
++expr;
}
```

The compiler produces `test.cpp(3): warning C5214: applying '++' to an operand with a volatile qualified type is deprecated in C++20`.

In C++20, compound assignment operators (operators of the form `@=`) were deprecated. In C++23, compound operators excluded in C++20 are no longer deprecated. For example, in C++23 the following code doesn't produce a warning, whereas it does in C++20:

```cpp
void f(volatile int& e1, int e2)
{
e1 += e2;
}
```

For more information about this change, see [CWG:2654](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#2654)

### Rewriting equality in expressions is less of a breaking change (P2468R2)

In C++20, [P2468R2](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2468r2.html) changed the compiler to accept code such as:

```cpp
struct S
{
bool operator==(const S&);
bool operator!=(const S&);
};
bool b = S{} != S{};
```

The compiler accepts this code, which means that the compiler is more strict with code such as:

```c++
struct S
{
operator bool() const;
bool operator==(const S&);
};

bool b = S{} == S{};
```

Version 17.5 of the compiler accepts this program. Version 17.6 of the compiler rejects it. To fix it, add `const` to `operator==` to remove the ambiguity. Or, add a corresponding `operator!=` to the definition as shown in the following example:

```cpp
struct S
{
operator bool() const;
bool operator==(const S&);
bool operator!=(const S&);
};

bool b = S{} == S{};
```

Microsoft C/C++ compiler versions 17.5 and 17.6 accept the previous program, and calls `S::operator==` in both versions.

The general programming model outlined in P2468R2 is that if there's a corresponding `operator!=` for a type, it typically suppresses the rewrite behavior. Adding a corresponding `operator!=` is the suggested fix for code that previously compiled in C++17. For more information, see [Programming Model](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2468r2.html#programming-model).

## <a name="improvements_174"></a> Conformance improvements in Visual Studio 2022 version 17.4

Expand Down Expand Up @@ -58,7 +132,7 @@ enum Changed

In versions of Visual Studio before Visual Studio 2022 version 17.4, the C++ compiler didn't correctly model the types of enumerators. It could assume an incorrect type in enumerations without a fixed underlying type before the closing brace of the enumeration. Under [`/Zc:enumTypes`](../build/reference/zc-enumtypes.md), the compiler now correctly implements the standard behavior.

The C++ Standard specifies that within an enumeration definition of no fixed underlying type, the types of enumerators are determined by their initializers. Or, for the enumerators with no initializer, by the type of the previous enumerator (accounting for overflow). Previously, such enumerators were always given the deduced type of the enumeration, with a placeholder for the underlying type (typically **`int`**).
The C++ Standard specifies that within an enumeration definition of no fixed underlying type, initializers determine the types of enumerators. Or, for the enumerators with no initializer, by the type of the previous enumerator (accounting for overflow). Previously, such enumerators were always given the deduced type of the enumeration, with a placeholder for the underlying type (typically **`int`**).

When enabled, the **`/Zc:enumTypes`** option is a potential source and binary breaking change. It's off by default, and not enabled by **`/permissive-`**, because the fix may affect binary compatibility. Some enumeration types change size when the conformant fix is enabled. Certain Windows SDK headers include such enumeration definitions.

Expand Down Expand Up @@ -252,9 +326,9 @@ void f()

Visual Studio 2022 version 17.1 contains the following conformance improvements, bug fixes, and behavior changes in the Microsoft C/C++ compiler.

### Detect ill-formed capture default in non-local lambda-expressions
### Detect ill-formed capture default in nonlocal lambda-expressions

The C++ Standard only allows a lambda expression in block scope to have a capture-default. In Visual Studio 2022 version 17.1 and later, the compiler detects when a capture default isn't allowed in a non-local lambda expression. It emits a new level 4 warning, C5253.
The C++ Standard only allows a lambda expression in block scope to have a capture-default. In Visual Studio 2022 version 17.1 and later, the compiler detects when a capture default isn't allowed in a nonlocal lambda expression. It emits a new level 4 warning, C5253.

This change is a source breaking change. It applies in any mode that uses the new lambda processor: **`/Zc:lambda`**, **`/std:c++20`**, or **`/std:c++latest`**.

Expand All @@ -267,7 +341,7 @@ In Visual Studio 2022 version 17.1 this code now emits an error:

auto incr = [=](int value) { return value + 1; };

// capture_default.cpp(3,14): error C5253: a non-local lambda cannot have a capture default
// capture_default.cpp(3,14): error C5253: a nonlocal lambda cannot have a capture default
// auto incr = [=](int value) { return value + 1; };
// ^
```
Expand Down Expand Up @@ -301,7 +375,7 @@ int main(void)
// C4113: 'int (__cdecl *)(char *)' differs in parameter lists from 'int (__cdecl *)(int)'
```

### Error on a non-dependent `static_assert`
### Error on a nondependent `static_assert`

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 as soon as 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.

Expand Down