July 2025

What’s New for C++ Developers in Visual Studio 2022 17.14 -- Sy Brand

RE1Mu3b.pngVisual Studio 2022 version 17.14 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.

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

by Sy Brand

From the article:

We’ve made a myriad of fixes and improvements to the MSVC compiler and standard library. See C++ Language Updates in MSVC in Visual Studio 2022 17.14 for a full list of changes on the compiler side, and the STL Changelog for all the standard library updates.

Compiler

We’ve added support for several C++23 features, which are available under the /std:c++latest and /std:c++23preview flags.

You can now omit () in some forms of lambdas that previously required them, thanks to P1102R2:

auto lambda = [] constexpr { }; //no '()' needed after the capture list
We implemented if consteval, with which you can run different code depending on whether the statement is executed at compile time or run time. This is useful for cases where your run time version can be heavily optimized with compiler intrinsics or inline assembly that are not available at compile time:
constexpr size_t strlen(char const* s) {
    if consteval {
        // if executed at compile time, use a constexpr-friendly algorithm
        for (const char *p = s; ; ++p) {
            if (*p == '\0') {
                return static_cast<std::size_t>(p - s);
            }
        }
    } else {
        // if executed at run time, use inline assembly
        __asm__("SSE 4.2 magic");
    }
}

C++26: Erroneous Behaviour -- Sandor Dargo

logo.pngC++’s undefined behaviour impacts safety. Sandor Dargo explains how and why uninitialised reads will become erroneous behaviour in C++26, rather than being undefined behaviour.

C++26: Erroneous Behaviour

by Sandor Dargo

From the article:

If you pick a random talk at a C++ conference these days, there is a fair chance that the speaker will mention safety at least a couple of times. It’s probably fine like that. The committee and the community must think about improving both the safety situation and the reputation of C++.

If you follow what’s going on in this space, you are probably aware that people have different perspectives on safety. I think almost everybody finds it important, but they would solve the problem in their own way.

A big source of issues is certain manifestations of undefined behaviour. It affects both the safety and the stability of software. I remember that a few years ago when I was working on some services which had to support a 10× growth, one of the important points was to eliminate undefined behaviour as much as possible. One main point for us was to remove uninitialized variables which often lead to crashing services.

Thanks to P2795R5 by Thomas Köppe, uninitialized reads won’t be undefined behaviour anymore – starting from C++26. Instead, they will get a new behaviour called ‘erroneous behaviour’.

The great advantage of erroneous behaviour is that it will work just by recompiling existing code. It will diagnose where you forgot to initialize variables. You don’t have to systematically go through your code and let’s say declare everything as auto to make sure that every variable has an initialized value. Which you probably wouldn’t do anyway.

Writing Senders -- Lucian Radu Teodorescu

logo.pngSenders/receivers can be used to introduce concurrency. Lucian Radu Teodorescu describes how to implement senders.

Writing Senders

by Lucian Radu Teodorescu

From the article:

If people are just using frameworks based on std::execution, they mainly need to care about senders and schedulers. These are user-facing concepts. However, if people want to implement sender-ready abstractions, they also need to consider receivers and operation states – these are implementer-side concepts. As this article mainly focuses on the implementation of sender abstractions, we need to discuss these two concepts in more detail.

A receiver is defined in P2300 as “a callback that supports more than one channel” [P2300R10]. The proposal defines a concept for a receiver, unsurprisingly called receiver. To model this concept, a type needs to meet the following conditions:

  • It must be movable and copyable.
  • It must have an inner type alias named receiver_concept that is equal to receiver_t (or a derived type).
  • std::execution::get_env() must be callable on an object of this type (to retrieve the environment of the receiver).

A receiver is the object that receives the sender’s completion signal, i.e., one of set_value()set_error(), or set_stopped(). As explained in the December 2024 issue [Teodorescu24], a sender may have different value completion types and different error completion types. For example, the same sender might sometimes complete with set_value(int, int), sometimes with set_value(double), sometimes with set_error(std::exception_ptr), sometimes with set_error(std::error_code), and sometimes with set_stopped(). This implies that a receiver must also be able to accept multiple types of completion signals.