Today, I complete my tour through the C++20 core language features with a few small improvements. One interesting of these minor improvements is that most of volatile has been deprecated.
The abstract in the proposal P1152R0 briefly describes the changes that volatile undergoes: “The proposed deprecation preserves the useful parts of volatile, and removes the dubious / already broken ones. This paper aims at breaking at compile-time code which is today subtly broken at runtime or through a compiler update. “
Before I show you what semantic of volatile is preserved, I want to start with the deprecated features:
- Deprecate volatile compound assignment, and pre/post increment/decrement
- Deprecate volatile qualification of function parameters or return types
- Deprecate volatile qualifiers in a structured binding declaration
If you want to know all the sophisticated details, I strongly suggest you watch the CppCon 2019 talk “Deprecating volatile” from JF Bastien. Here are a few examples from the talk referring to used numbers (1) to (3).
I didn’t answer the crucial question: When should you use volatile? A note from the C++ standard says that “volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation.” This means for a single thread of execution that, the compiler must perform load or store operations in the executable as often as they occur in the source code. volatile operations, therefore, cannot be eliminated or reordered. Consequently, you can use volatile objects to communicate with a signal handler but not with another thread of execution.
To summarize, volatile avoids aggressive optimization and has no multithreading semantics.
I present the remaining minor improvements with a short example that runs in the Compiler Explorer.
Range-based for-loop with Initializers
With C++20, you can directly use a range-based for-loop with an initializer.
The range-based for-loop uses in line (1) a std::vector, in line (2) a std::initializer_list, and line (3) a std::string. Additionally, in lines (1) and line (2), I apply automatic type deduction for class templates we have had since C++17. Instead of std::vector<int> and std::initalizer_list<int>, I write std::vector and std::initializer_list.
With GCC 10.2 and Compiler Explorer, I get the expected output.
virtual constexpr Functions
A constexpr function has the potential to run at compile-time but can also be executed at run-time. Consequently, you can make a constexpr function with C++20 virtual. Both directions are possible. Neither can a virtual constexpr function override a non-constexpr function nor can a virtual non-constexpr function override a constexpr virtual function. I want to emphasize that override implies that the regarding function of a base class is virtual.
The following program shows both combinations.
Line (1) uses virtual dispatch (late binding) via a pointer, and line (2) uses virtual dispatch via reference. Once more, here is the output with GCC 10.2 and the Compiler Explorer.
The new Character Type for UTF-8 Strings: char8_t
Additionally, to the character types char16_t and char32_t from C++11, C++20 gets the new character type char8_t.char8_t is large enough to represent any UTF-8 code unit (8 bits). It has the same size, signedness, and alignment as an unsigned char, but is a distinct type.
Consequently, C++20 has a new typedef for the character type char8_t (1) and a new UTF-8 string literal (2).
The following program shows the straightforward usage of char8_t:
Without further ado. Here is the output of the program on the Compiler Explorer.
using enum in Local Scopes
A using enum declaration introduces the enumerators of the named enumeration in the local scope.
The using enum declaration in (1) introduces the enumerators of the scoped enumerations Color into the local scope. From then on, the enumerators can be used unscoped (2). This time, the only C++ compiler supporting using enum is the Microsoft Compiler 19.24:
Default member initializers for bit-fields
First, what is a bit field? Here is the definition of Wikipedia: “A bit field is a data structure used in computer programming. It consists of a number of adjacent computer memory locations which have been allocated to hold a sequence of bits, stored so that any single bit or group of bits within the set can be addressed. A bit field is most commonly used to represent integral types of known, fixed bit-width.”
With C++20, we can default initialize the members of a bit-field:
According to the member of a class (1) with C++11, the members of the bit-field can have default initializers (2) with C++20. Finally, here is the output of the program with the Clang 10.0 compiler:
A Short Writing Break
In the next fortnight, I will be in Italy, so I will not write a regular post.
If you want to read one of my more than 300 posts on modern C++, I created a visual tour through my blog. This visual tour explains the TOC, categories, tags, archive, and search system and should help you find the post you are looking for.
Here you go https://youtu.be/hrXoVSi0O28.
After my short break, I continue my journey through C++20 with the new library. In particular, I will write about std::span.
Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, Rob North, Bhavith C Achar, and Marco Parri Empoli.
Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, Slavko Radman, and David Poole.
|My special thanks to Embarcadero|
|My special thanks to PVS-Studio|
|My special thanks to Tipi.build|
|My special thanks to Take Up Code|
I’m happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.
- Embedded Programmierung mit modernem C++ 12.12.2023 – 14.12.2023 (Präsenzschulung, Termingarantie)
Standard Seminars (English/German)
Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.
- C++ – The Core Language
- C++ – The Standard Library
- C++ – Compact
- C++11 and C++14
- Concurrency with Modern C++
- Design Pattern and Architectural Pattern with C++
- Embedded Programming with Modern C++
- Generic Programming (Templates) with C++
- Clean Code with Modern C++
- Phone: +49 7472 917441
- Mobil:: +49 176 5506 5086
- Mail: schulung@ModernesCpp.de
- German Seminar Page: www.ModernesCpp.de
- Mentoring Page: www.ModernesCpp.org
Modernes C++ Mentoring,