What’s New for C++ Developers in Visual Studio 2022 17.4

We are happy to announce that Visual Studio 2022 version 17.4 is now generally available! This post summarizes the new features you can find in this release for C++. You can download Visual Studio 2022 from the Visual Studio downloads page or upgrade your existing installation by following the Update Visual Studio Learn page.

In 17.3, Visual Studio became available as a native Arm64 application. We have continued work on supporting more development scenarios and are pleased to announce that the native Arm64 toolchain is now ready for production use!

The “Desktop development with C++” and “Game development with C++” workloads are enabled for native Arm64 development. Please give them a try and let us know your feedback!

One of our major investments for this release has been in improved compiler diagnostics. New C++ features like concepts and ranges present the opportunity for more expressive code and better-defined APIs. However, to make the most of them, better diagnostics are required from tooling so that constraint failures can be pinpointed and resolved. See Xiang Fan’s blog post on The Future of C++ Compiler Diagnostics in MSVC and Visual Studio for all the details, but here’s a quick example of the improvement, showing more complete information on overload resolution failures, and information on why a given constraint failed:

struct cat {}; struct dog {}; // can pet cats and dogs void pet(cat); void pet(dog); template concept has_member_pettable = requires (T t) { t.pet(); }; // allow calling as a non-member template void pet(T); int main() {     pet(0); //oh no }

Error in 17.3

(16,10): error C2665: 'pet': none of the 2 overloads could convert all the argument types pet(0); //oh no ^(6,6): note: could be 'void pet(dog)' void pet(dog); ^(5,6): note: or 'void pet(cat)' void pet(cat); ^(16,5): note: 'void pet(cat)': cannot convert argument 1 from 'int' to 'cat' pet(0); //oh no ^(16,10): note: No constructor could take the source type, or constructor overload resolution was ambiguous pet(0); //oh no ^(5,6): note: see declaration of 'pet' void pet(cat); ^(16,10): note: while trying to match the argument list '(int)' pet(0); //oh no

Error in 17.4

(16,5): error C2665: 'pet': no overloaded function could convert all the argument types pet(0); //oh no ^(6,6): note: could be 'void pet(dog)' void pet(dog); ^(16,5): note: 'void pet(dog)': cannot convert argument 1 from 'int' to 'dog' pet(0); //oh no ^(16,9): note: No constructor could take the source type, or constructor overload resolution was ambiguous pet(0); //oh no ^(5,6): note: or 'void pet(cat)' void pet(cat); ^(16,5): note: 'void pet(cat)': cannot convert argument 1 from 'int' to 'cat' pet(0); //oh no ^(16,9): note: No constructor could take the source type, or constructor overload resolution was ambiguous pet(0); //oh no ^(13,6): note: or 'void pet(T)' void pet(T); ^(16,5): note: the associated constraints are not satisfied pet(0); //oh no ^(12,11): note: the concept 'has_member_pettable' evaluated to false template ^(9,48): note: the expression is invalid concept has_member_pettable = requires (T t) { t.pet(); }; ^(16,5): note: while trying to match the argument list '(int)' pet(0); //oh no ^

Here is a Compiler Explorer link to see the difference.

As part of this work, we’ve also added experimental support for outputting compiler diagnostics as SARIF. This is accessible with the experimental flag /experimental:log.

In addition to improved diagnostics, we’ve expanded the compiler’s Named Return Value Optimization (NRVO) capabilities. See Bran Hagger’s blog post Improving Copy and Move Elision for details. The main improvements are in enabling NRVO for cases which involve exception handling or loops. For example, in 17.3, the copy/move of result when returning it would not be elided, but now will be.

Foo ReturnInALoop(int iterations) {     for (int i = 0; i < iterations; ++i) {         Foo result;         if (i == (iterations / 2)) {             return result; //copy/move elided         }     } }

You can see the difference in generated assembly at this Compiler Explorer link.

Containers are a great way to package up everything for running an application. Through a Dockerfile, all prerequisites are captured so that there is a consistent runtime environment anywhere the container is deployed and run. Dev Containers expand this concept to capture everything necessary for developing and building an application in the container. You can now use Dev Containers for your C++ projects in Visual Studio. You can learn more about this feature in our Dev Containers for C++ blog post.

Alert box saying

Connecting to remote systems with the Connection Manager now supports SSH ProxyJump, which is used to access a SSH host via another SSH host (for example, to access a host behind a firewall).

Test Explorer used to expose internal prefixes of CTest tests, making the list harder to read and navigate. We’ve improved this, grouping all of them under a single header. Here is the before and after:

List from test explorer showing the weird prefixes Cleaner list under a ctest header

We made several updates to the additional tools which are shipped with Visual Studio in some workloads.

If you’re using Visual Studio on Arm64 machines, you will now get Arm64 builds of CMake and Ninja through the CMake components in the Visual Studio installer.

We’ve updated the version of CMake which we ship to version 3.24.1. This release comes with many new features, including a –fresh CLI flag for removing the CMake cache, path comparison in if expressions, and version 5 of CMakePresets.json. We’ll be adding support for CMakePresets.json version 5 in our 17.5 release of Visual Studio 2022, but 17.4 comes with added support for version 4. See the CMake release notes for all the new goodies.

We also updated the version of LLVM which we ship to version 15.0.1. See the LLVM and Clang release notes for what is available.

When using the “Create Declaration/Definition” feature, it used to be that the new code would open up in a small window to give you a “peek”. This is now configurable: you can select between peeking (the default), or opening the document,, or no navigation. The setting is under Options > Text Editor > C/C++ > Advanced > Refactoring.

Options pane showing

We fixed a consistency gap between IntelliSense and MSBuild for pre-compiled headers. It used to be that, when a PCH was used via /Yu and force-included via /FI, IntelliSense would always process it first, before any other headers included via /FI. This did not match the build behavior, so with this change /FI headers are processed in the order they are specified.

We are also continuing to improve the performance of the IDE. In this release, we improved indexing performance when opening a new solution. Large projects could see a 20-35% improvement from 17.3.

We enrich some of our code analysis warnings with “key events” information which describes how the result of the analysis was arrived at. We improved and expanded this feature by adding this information to more analyses and giving you new ways to visualize it in Visual Studio.

For example, when the SARIF Viewer extension is installed, the key event information will now be used to annotate the source directly.

Code annotated with reasoning behind an initialization code analysis warning

See the Microsoft C++ Code Analysis Warnings with Key Events blog post for all the details.

We’re continuing to track the latest developments in C++ standardization. You can see the latest and upcoming STL features in our Changelog on GitHub, but here are some of the ones I’m most excited about:

  • P0881R7  
  • P1328R1  constexpr type_info::operator==()
  • P2440R1  ranges::iota, ranges::shift_left, ranges::shift_right
  • P2441R2  views::join_with
  • P2302R4  ranges::contains, ranges::contains_subrange

Conformance work also extends to IntelliSense, which now has support for C23 attributes, and we are continuing to improve the support for C++20 modules.

vcpkg is now 6 years old and has over 2000 open-source libraries available!

We’re continuing to add new features both to vcpkg itself, and to Visual Studio to improve integration. For example, vcpkg artifacts is a feature which allows you to describe the tools and environment necessary to build your application. We have now added support to Visual Studio for vcpkg artifacts with CMake projects, such that if your project includes a vcpkg manifest, the environment will be activated automatically on project open. You can learn more about this in the vcpkg environment activation in Visual Studio blog post.

Popup saying

Other notable improvements since the last release are making the “name” and “version” fields in vcpkg.json optional, adding schemata for all vcpkg json formats, and improving cross-compilation for macOS. You can read more details about these and more in our monthly blog posts from August and September.

We’re working hard on the Unreal Engine integration into Visual Studio. As of 17.4, you can now see which Unreal Engine Blueprints reference, use, and inherit from C++ classes, directly in the IDE. To enable this feature, ensure that the “IDE support for Unreal Engine” component is enabled in the VS Installer, and download the Visual Studio Integration Tool from the Unreal Marketplace.

Popup showing the references to a given blueprint

Keep an eye out for more new features in 17.5, and please let us know what you think of the Blueprints integration!

We are very much interested in your feedback to continue to improve this experience. The comments below are open. Feedback can also be shared through the Developer Community. You can also reach us on Twitter (@VisualC), or via email at [email protected].

Sy Brand C++ Developer Advocate, C++ Team

Get paid to share your bandwidth! Peer2Profit is the BEST side income for you! → https://www.peer2profit.io