C++23: Bitwise Operations -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGWhile C++ is getting increasingly expressive with each new standard, we must not forget its origins. It is inherently a low-level language which operates close to the hardware level and allows operations that languages such as Javascript cannot even express.

A part of providing low-level functionalities is to be able to work on a byte or even on a bit level. In this post, we are going to see what related features C++23 brings or modifies.

C++23: Bitwise Operations

by Sandor Dargo

From the article:

constexpr std::bitset

To be fair, we already covered this earlier last year in C++23: Even more constexpr. But as I’m using this feature to demonstrate the next one, I decided to mention it again.

P2417R2 extends the constexpr interface of std::bitset. So far, only one of the constructors and operator[] was marked as constexpr. However, since std::string can be constexpr, all the internals - and therefore the full API - of std::bitset can be constexpr.

If you’re unfamiliar with std::bitset, it represents the object you pass in as a sequence of bits. You have to pass the number of bits as a non-type template argument.

#include <bitset>
#include <iostream>

int main()
{
    constexpr short i = 15;
    constexpr int numberOfBitsInInt = sizeof(i) * 8;
    std::cout << "i:" << i << ", i as binary: " << std::bitset<numberOfBitsInInt>(i) << '\n';
}
/*
i:15, i as binary: 0000000000001111
*/

It’s more capable than that, it also offers several ways to query the individual bits or set them.

C++23 likes to move it! -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGC++23 is going to bring us a few changes regarding move operations. It mostly means extended support in the standard library, but there is also one change directly in the language. Let’s start with that.

C++23 likes to move it!

by Sandor Dargo

From the article:

P2266R3 is a quite great proposal both in terms of its high-quality explanation and the amount of proposed changes in wording. I think if you’re interested in exploring a readable proposal, this might be the one.

Let me try to summarize it briefly.

Since the introduction of move semantics and rvalue references in C++11, we can return move-only types by value:

struct Widget {
    Widget(Widget&&);
};

Widget one(Widget w) {
    return w;
}
C++14 extended this support so that even converting constructors accepting an rvalue type can be called to invoke an implicit move.
struct RRefTaker {
    RRefTaker(Widget&&); // here is the converting constructor
};

RRefTaker two(Widget w) {
    return w;
}

As you can see, the two examples...

Parsing Numbers At Compile Time with C++17, C++23, and C++26 -- Bartlomiej Filipek

modern-parsingnum.pngThanks to the powerful constexpr keyword and many enhancements in recent C++ standards, we can now perform a lot of computations at compile time. In this text, we’ll explore several techniques for parsing integers, including the “naive” approach, C++23,from_chars,std::optional, std::expected, and even some upcoming features in C++26.

Parsing Numbers At Compile Time with C++17, C++23, and C++26

by Bartlomiej Filipek

From the article:

Why at compile time?

While it may sound like a theoretical experiment, since C++11 we can shift more and more computations to compile-time. Here are some key areas and examples where constexpr can be beneficial:

Starting easy from C++17 

Starting with C++17, we are now capable of writing complex constexpr functions. However, our ability to do so is still limited by the range of algorithms available in that context. Luckily, with the introduction of string_view in that version of C++, there is no longer any need to work with “raw” const char* buffers.

Class Invariants -- Andrzej Krzemieński

Andrzej-Krzemieński.pngThis article explores the concept of class invariants in C++ and their significance in maintaining code integrity and abstraction. It highlights the difference between struct and class definitions and discusses the role of class invariants in guaranteeing the correctness of class objects. The article also touches upon the trade-offs between strong and weak invariants and provides insights into when to define a new class with proper invariants.

Class Invariants

by Andrzej Krzemieński

From the article:

The primary motivation for defining a class in C++ is to reflect and maintain a class invariant. In this post we will see what class invariants are and how you deal with them. Class invariants are important part of C++, even though there is no “invariant” keyword in C++.

Contrast the following two class definitions:

struct Point
{
  int x;
  int y;
};
class Range
{
  int _min;
  int _max;

public:
  // ...
};

In C++ a struct is practically a class but with a different default member access. The first is an aggregate: it only allows two pieces of data to travel together. If it was not for the nice member names, we might have as well used std::pair<int, int> instead. 

Optimizing the Unoptimizable: A Journey to Faster C++ Compile Times -- Victor Zverovich

zverovich-compiletimes.jpgIn this post, Victor talks about bringing compile times of the {fmt} library on par with the C standard I/O library (stdio).

Optimizing the Unoptimizable: A Journey to Faster C++ Compile Times

by Victor Zverovich

From the article:

First some background: {fmt} is a popular open-source formatting library for C++ that provides a better alternative to C++ iostreams and C stdio. It has already surpassed stdio in many areas:

  • Type safety with compile-time format string checks available by default since C++20 and as an opt in for C++14/17. Runtime format strings are also safe to use in {fmt} which is impossible to achieve in printf.
  • Extensibility: user-defined type can be made formattable and most standard library types such as containers, dates and times are formattable out of the box.
  • Performance: {fmt} is significantly faster than common standard library implementations of printf, in some cases by an order of magnitude (e.g. on floating-point formatting).
  • Portable Unicode support.

However, one area where stdio remained significantly better was compile times. 

Seastar, ScyllaDB, and C++23

Seastar announces that now that C++23 is available, they will support C++23 and C++20 (dropping support for C++17) in accordance with their support policy

Seastar, ScyllaDB, and C++23

By Avi Kivity

From the article:

Seastar is an open-source (Apache 2.0 licensed) C++ framework for I/O intensive asynchronous computing, using the thread-per-core model. Seastar underpins several high- performance distributed systems: ScyllaDB, Redpanda, and Ceph Crimson. Seastar source is available on github. As a C++ framework, Seastar must choose which C++ versions to support. The support policy is last-two-versions. That means that at any given time, the most recently released version as well as the previous one are supported, but earlier versions cannot be expected to work. This policy gives users of the framework three years to upgrade to the next C++ edition while not constraining Seastar to ancient versions of the language.

Now that C++23 has been ratified, Seastar now officially supports C++20 and C++23. The previously supported C++17 is now no longer supported.

The Case of the Vector With an Impossibly Large Size -- Raymond Chen

RaymondChen_5in-150x150.jpgIn this software troubleshooting case, a customer experienced program crashes, and a detailed analysis of the code revealed several issues. The primary problem stemmed from lazy initialization of a widget list, leading to inconsistent vector states and potential crashes. Additionally, a multithreading issue was identified, highlighting the importance of thread-safety mechanisms in code that can be accessed concurrently.

The Case of the Vector With an Impossibly Large Size

by Raymond Chen

From the article:

A customer had a program that crashed with this stack:

contoso!Widget::GetCost
contoso!StandardWidgets::get_TotalCost+0x12f
rpcrt4!Invoke+0x73
rpcrt4!Ndr64StubWorker+0xb9b
rpcrt4!NdrStubCall3+0xd7
combase!CStdStubBuffer_Invoke+0xdb
combase!ObjectMethodExceptionHandlingAction<<lambda_...> >+0x47
combase!DefaultStubInvoke+0x376
combase!ServerCall::ContextInvoke+0x6f3
combase!ComInvokeWithLockAndIPID+0xacb
combase!ThreadInvoke+0x103
rpcrt4!DispatchToStubInCNoAvrf+0x18
rpcrt4!RPC_INTERFACE::DispatchToStubWorker+0x1a9
rpcrt4!RPC_INTERFACE::DispatchToStubWithObject+0x1a7
rpcrt4!LRPC_SCALL::DispatchRequest+0x308
rpcrt4!LRPC_SCALL::HandleRequest+0xdcb
rpcrt4!LRPC_SASSOCIATION::HandleRequest+0x2c3
rpcrt4!LRPC_ADDRESS::HandleRequest+0x183
rpcrt4!LRPC_ADDRESS::ProcessIO+0x939
rpcrt4!LrpcIoComplete+0xff
ntdll!TppAlpcpExecuteCallback+0x14d
ntdll!TppWorkerThread+0x4b4
kernel32!BaseThreadInitThunk+0x18
ntdll!RtlUserThreadStart+0x21

They wondered if some recent change to Windows was the source of the problem, since it didn’t happen as much in earlier versions of Windows.

 

2024-02 Mailing Available

The 2024-02 mailing of new standards papers is now available.

 

WG21 Number Title Author Document Date Mailing Date Previous Version Subgroup
P0493R5 Atomic maximum/minimum Al Grant 2024-02-12 2024-02 P0493R4 SG1 Concurrency and Parallelism,LWG Library
P0843R10 inplace_vector Gonzalo Brito Gadeschi 2024-02-12 2024-02 P0843R9 LWG Library
P0876R15 fiber_context - fibers without scheduler Oliver Kowalke 2024-02-14 2024-02 P0876R14 CWG Core,LWG Library
P1061R7 Structured Bindings can introduce a Pack Barry Revzin 2024-02-14 2024-02 P1061R6 EWG Evolution
P1144R10 std::is_trivially_relocatable Arthur O'Dwyer 2024-02-15 2024-02 P1144R9 EWG Evolution,LEWG Library Evolution
P1729R4 Text Parsing Elias Kosunen 2024-02-11 2024-02 P1729R3 SG9 Ranges,SG16 Unicode,LEWG Library Evolution
P2047R7 An allocator-aware optional type Nina Ranns 2024-02-15 2024-02 P2047R6 LEWG Library Evolution
P2075R4 Philox as an extension of the C++ RNG engines Ilya Burylov 2024-02-14 2024-02 P2075R3 LEWG Library Evolution
P2249R5 Mixed comparisons for smart pointers Giuseppe D'Angelo 2024-02-15 2024-02 P2249R4 LEWG Library Evolution
P2249R6 Mixed comparisons for smart pointers Giuseppe D'Angelo 2024-02-15 2024-02 P2249R5 LEWG Library Evolution
P2299R4 `mdspan`s of All Dynamic Extents Bryce Adelstein Lelbach 2024-02-15 2024-02 P2299R3 LEWG Library Evolution
P2389R0 `dextents` Index Type Parameter Nevin Liber 2024-02-15 2024-02   LEWG Library Evolution
P2422R0 Remove nodiscard annotations from the standard library specification Ville Voutilainen 2024-02-09 2024-02   LEWG Library Evolution,LWG Library
P2643R2 Improving C++ concurrency features Gonzalo Brito Gadeschi 2024-01-31 2024-02 P2643R1 LEWG Library Evolution
P2686R3 constexpr structured bindings and references to constexpr variables Corentin Jabot 2024-02-15 2024-02 P2686R2 EWG Evolution,CWG Core
P2688R1 Pattern Matching: `match` Expression Michael Park 2024-02-15 2024-02 P2688R0 EWG Evolution
P2721R0 Deprecating function Michael Florian Hava 2024-02-14 2024-02   LEWG Library Evolution
P2727R4 std::iterator_interface Zach Laine 2024-02-05 2024-02 P2727R3 LEWG Library Evolution
P2746R4 Deprecate and Replace Fenv Rounding Modes Hans Boehm 2024-02-14 2024-02 P2746R3 SG6 Numerics,LEWG Library Evolution
P2758R2 Emitting messages at compile time Barry Revzin 2024-02-14 2024-02 P2758R1 EWG Evolution,LEWG Library Evolution
P2781R4 std::constexpr_wrapper Zach Laine 2024-02-11 2024-02 P2781R3 LEWG Library Evolution
P2786R4 Trivial Relocatability For C++26 Mungo Gill 2024-02-09 2024-02 P2786R3 EWG Evolution,LEWG Library Evolution
P2822R0 Providing user control of associated entities of class types Lewis Baker 2024-02-15 2024-02   EWG Evolution
P2835R3 Expose std::atomic_ref's object address Gonzalo Brito Gadeschi 2024-01-31 2024-02 P2835R2 LEWG Library Evolution
P2845R6 Formatting of std::filesystem::path Victor Zverovich 2024-01-27 2024-02 P2845R5 SG16 Unicode,LEWG Library Evolution,LWG Library
P2863R4 Review Annex D for C++26 Alisdair Meredith 2024-02-15 2024-02 P2863R3 EWG Evolution,LEWG Library Evolution
P2875R3 Undeprecate `polymorphic_allocator::destroy` For C++26 Alisdair Meredith 2024-02-15 2024-02 P2875R2 LEWG Library Evolution
P2893R2 Variadic Friends Jody Hagins 2024-02-12 2024-02 P2893R1 CWG Core
P2900R5 Contracts for C++ Joshua Berne 2024-02-15 2024-02 P2900R4 EWG Evolution,LEWG Library Evolution
P2927R1 Observing exceptions stored in exception_ptr Gor Nishanov 2024-02-15 2024-02 P2927R0 LEWG Library Evolution
P2964R0 Allowing user-defined types in std::simd Daniel Towner 2024-02-09 2024-02   SG1 Concurrency and Parallelism,LEWG Library Evolution
P2988R2 std::optional\ Steve Downey 2024-02-15 2024-02 P2988R1 LEWG Library Evolution,LWG Library
P2988R3 std::optional<T&> Steve Downey 2024-02-15 2024-02 P2988R2 LEWG Library Evolution,LWG Library
P2989R1 A Simple Approach to Universal Template Parameters Corentin Jabot 2024-02-15 2024-02 P2989R0 EWG Evolution
P2992R1 Attribute [[discard("reason")]] Giuseppe D'Angelo 2024-02-02 2024-02 P2992R0 SG22 Compatibility,EWG Evolution
P2994R1 On the Naming of Packs Barry Revzin 2024-02-14 2024-02 P2994R0 EWG Evolution
P2996R2 Reflection for C++26 Barry Revzin 2024-02-15 2024-02 P2996R1 EWG Evolution
P3002R1 Policies for Using Allocators in New Library Classes Pablo Halpern 2024-02-15 2024-02 P3002R0 LEWG Library Evolution
P3004R0 Principled Design for WG21 John Lakos 2024-02-15 2024-02   EWG Evolution,LEWG Library Evolution
P3005R0 Memorializing Principled-Design Policies for WG21 John Lakos 2024-02-14 2024-02   EWG Evolution,LEWG Library Evolution
P3008R1 Atomic floating-point min/max Gonzalo Brito Gadeschi 2024-01-31 2024-02 P3008R0 SG6 Numerics,LEWG Library Evolution
P3016R2 Resolve inconsistencies in begin/end for valarray and braced initializer lists Arthur O'Dwyer 2024-02-12 2024-02 P3016R1 LEWG Library Evolution
P3019R4 Vocabulary Types for Composite Class Design Jonathan Coe 2024-02-05 2024-02 P3019R3 LEWG Library Evolution
P3019R5 Vocabulary Types for Composite Class Design Jonathan Coe 2024-02-07 2024-02 P3019R4 LEWG Library Evolution
P3019R6 Vocabulary Types for Composite Class Design Jonathan Coe 2024-02-11 2024-02 P3019R5 LEWG Library Evolution
P3032R0 Less transient constexpr allocation Barry Revzin 2024-02-13 2024-02   EWG Evolution
P3045R0 Quantities and units library Mateusz Pusz 2024-02-15 2024-02   SG6 Numerics,SG16 Unicode,LEWGI SG18: LEWG Incubator
P3047R0 Remove deprecated namespace `relops` from C++26 Alisdair Meredith 2024-02-15 2024-02   LEWG Library Evolution
P3052R1 view_interface::at() Hewill Kang 2024-01-29 2024-02 P3052R0 SG9 Ranges,SG23 Safety and Security
P3055R1 Relax wording to permit relocation optimizations in the STL Arthur O'Dwyer 2024-02-12 2024-02 P3055R0 LEWG Library Evolution
P3060R1 Add std::views::upto(n) Weile Wei 2024-02-15 2024-02 P3060R0 SG9 Ranges,LEWG Library Evolution,LWG Library
P3068R0 Allowing exception throwing in constant-evaluation. Hana Dusíková 2024-02-11 2024-02   EWG Evolution
P3072R1 Hassle-free thread attributes Zhihao Yuan 2024-02-15 2024-02 P3072R0 LEWG Library Evolution
P3073R0 Remove evaluation_undefined_behavior and will_continue from the Contracts MVP Timur Doumler 2024-01-27 2024-02   SG21 Contracts
P3074R1 std::uninitialized<T> Barry Revzin 2024-01-30 2024-02 P3074R0 EWG Evolution
P3074R2 std::uninitialized<T> Barry Revzin 2024-02-13 2024-02 P3074R1 EWG Evolution
P3085R0 `noexcept` policy for SD-9 (throws nothing) Ben Craig 2024-02-10 2024-02   LEWG Library Evolution
P3088R0 Attributes for contract assertions Timur Doumler 2024-02-12 2024-02   SG21 Contracts
P3088R1 Attributes for contract assertions Timur Doumler 2024-02-13 2024-02 P3088R0 SG21 Contracts
P3090R0 std::execution Introduction Inbal Levi, Eric Niebler 2024-02-14 2024-02   LEWG Library Evolution
P3091R0 Better lookups for `map` and `unordered_map` Pablo Halpern 2024-02-06 2024-02   LEWGI SG18: LEWG Incubator
P3092R0 Modules ABI requirement Chuanqi Xu 2024-01-28 2024-02   SG15 Tooling,ARG ABI Review Group
P3093R0 Attributes on expressions Giuseppe D'Angelo 2024-02-02 2024-02   SG22 Compatibility,EWG Evolution
P3094R0 std::basic_fixed_string Mateusz Pusz 2024-02-05 2024-02   SG16 Unicode,LEWGI SG18: LEWG Incubator,LEWG Library Evolution
P3095R0 ABI comparison with reflection Saksham Sharma 2024-02-15 2024-02   SG7 Reflection,LEWG Library Evolution
P3096R0 Function Parameter Reflection in Reflection for C++26 Adam Lach 2024-02-14 2024-02   SG7 Reflection
P3101R0 Differentiating potentially throwing and nonthrowing violation handlers Ran Regev 2024-01-22 2024-02   SG21 Contracts
P3102R0 Refining Contract Violation Detection Modes Joshua Berne 2024-02-05 2024-02   SG21 Contracts
P3103R0 More bitset operations Jan Schultke 2024-01-24 2024-02   LEWGI SG18: LEWG Incubator
P3104R0 Bit permutations Jan Schultke 2024-01-25 2024-02   LEWGI SG18: LEWG Incubator
P3105R0 constexpr std::uncaught_exceptions() Jan Schultke 2024-01-25 2024-02   LEWGI SG18: LEWG Incubator
P3106R0 Clarifying rules for brace elision in aggregate initialization James Touton 2024-02-03 2024-02   CWG Core
P3107R0 Permit an efficient implementation of std::print Victor Zverovich 2024-02-03 2024-02   LEWG Library Evolution
P3109R0 A plan for std::execution for C++26 Lewis Baker 2024-02-12 2024-02   LEWG Library Evolution
P3110R0 Array element initialization via pattern expansion James Touton 2024-02-04 2024-02   EWGI SG17: EWG Incubator,EWG Evolution
P3112R0 Specify Constructor of std::nullopt_t Brian Bi 2024-02-14 2024-02   LEWG Library Evolution,LWG Library
P3113R0 Slides: Contract assertions, the noexcept operator, and deduced exception specifications Timur Doumler 2024-02-02 2024-02   SG21 Contracts
P3114R0 noexcept(contract_assert(_)) -- slides Andrzej Krzemieński 2024-02-02 2024-02   SG21 Contracts
P3115R0 Data Member, Variable and Alias Declarations Can Introduce A Pack Corentin Jabot 2024-02-15 2024-02   EWG Evolution
P3116R0 Policy for explicit Zach Laine 2024-02-08 2024-02   LEWG Library Evolution
P3117R0 Extending Conditionally Borrowed Zach Laine 2024-02-14 2024-02   SG9 Ranges,LEWG Library Evolution
P3122R0 [[nodiscard]] should be Recommended Practice Jonathan Wakely 2024-02-15 2024-02   LEWG Library Evolution,LWG Library
P3123R0 2024-02 Library Evolution Polls Inbal Levi 2024-02-15 2024-02   LEWG Library Evolution
P3126R0 Graph Library: Overview Phil Ratzloff 2024-02-12 2024-02   SG14 Low Latency,SG19 Machine Learning,LEWG Library Evolution
P3127R0 Graph Library: Background and Terminology Phil Ratzloff 2024-02-12 2024-02   SG14 Low Latency,SG19 Machine Learning,LEWG Library Evolution
P3128R0 Graph Library: Algorithms Phil Ratzloff 2024-02-12 2024-02   SG14 Low Latency,SG19 Machine Learning,LEWG Library Evolution
P3129R0 Graph Library: Views Phil Ratzloff 2024-02-12 2024-02   SG14 Low Latency,SG19 Machine Learning,LEWG Library Evolution
P3130R0 Graph Library: Graph Container Interface Phil Ratzloff 2024-02-12 2024-02   SG6 Numerics,SG14 Low Latency,SG19 Machine Learning,LEWG Library Evolution
P3131R0 Graph Library: Graph Containers Phil Ratzloff 2024-02-12 2024-02   SG6 Numerics,SG14 Low Latency,SG19 Machine Learning,LEWG Library Evolution
P3133R0 Fast first-factor finding function Chip Hogg 2024-02-14 2024-02   SG6 Numerics,LEWG Library Evolution
P3135R0 Hazard Pointer Extensions Maged Michael 2024-02-11 2024-02   SG1 Concurrency and Parallelism,LEWG Library Evolution,LWG Library
P3136R0 Retiring niebloids Tim Song 2024-02-14 2024-02   SG9 Ranges
P3137R0 views::to_input Tim Song 2024-02-14 2024-02   SG9 Ranges
P3138R0 views::cache_last Tim Song 2024-02-14 2024-02   SG1 Concurrency and Parallelism,SG9 Ranges
P3140R0 std::int_least128_t Jan Schultke 2024-02-14 2024-02   EWGI SG17: EWG Incubator,LEWGI SG18: LEWG Incubator
P3142R0 Printing Blank Lines with println Alan Talbot 2024-02-12 2024-02   LEWG Library Evolution
P3143R0 An in-depth walk through of the example in P3090R0 Lewis Baker 2024-02-13 2024-02   LEWG Library Evolution
P3144R0 Deprecate Delete of Incomplete Class Type Alisdair Meredith 2024-02-15 2024-02   SG12 Undefined and Unspecified Behavior,EWGI SG17: EWG Incubator
P3146R0 Clarifying std::variant converting construction Giuseppe D'Angelo 2024-02-13 2024-02   LEWG Library Evolution,LWG Library
P3147R0 A Direction for Vector Alan Talbot 2024-02-14 2024-02   LEWG Library Evolution
P3148R0 Formatting of chrono Time Values Alan Talbot 2024-02-14 2024-02   LEWG Library Evolution
P3149R0 async_scope -- Creating scopes for non-sequential concurrency Ian Petersen 2024-02-14 2024-02   SG1 Concurrency and Parallelism,LEWG Library Evolution
P3150R0 SG14: Low Latency/Games/Embedded/Financial Trading virtual Meeting Minutes 2023/12/13-2024/2/14 Michael Wong 2024-02-14 2024-02   SG14 Low Latency
P3151R0 SG19: Machine Learning virtual Meeting Minutes to 2023/12/14-2024/02/8 Michael Wong 2024-02-14 2024-02   SG19 Machine Learning
P3153R0 An allocator-aware variant type Nina Ranns 2024-02-15 2024-02   LEWG Library Evolution
P3154R0 Deprecating signed character types in iostreams Elias Kosunen 2024-02-15 2024-02   SG16 Unicode,LEWG Library Evolution
P3155R0 noexcept policy for SD-9 (The Lakos Rule) Timur Doumler 2024-02-15 2024-02   LEWG Library Evolution
P3156R0 empty_checkable_range Hewill Kang 2024-02-15 2024-02   LEWGI SG18: LEWG Incubator
P3157R0 Generative Extensions for Reflection Andrei Alexandrescu 2024-02-15 2024-02   SG7 Reflection
P3158R0 Headless Template Template Parameters James Touton 2024-02-15 2024-02   EWGI SG17: EWG Incubator,EWG Evolution
P3160R0 An allocator-aware `inplace_vector` Pablo Halpern 2024-02-15 2024-02   LEWG Library Evolution
P3300R0 C++ Asynchronous Parallel Algorithms Bryce Adelstein Lelbach 2024-02-15 2024-02   SG1 Concurrency and Parallelism,LEWG Library Evolution