News

Write More C++ Code Thanks to constexpr -- Andreas Fertig

me.pngSince its introduction, the constexpr keyword in C++ has steadily evolved with each new standard, becoming an increasingly powerful tool for compile-time computation and optimization. In this article, I’ll share a real-world example of how constexpr helped optimize memory usage and improve performance for an embedded system project, showcasing its potential to transform how we approach C++ programming.

Write More C++ Code Thanks to constexpr

by Andreas Fertig

From the article:

Since the keyword constexpr and its behavior got included in C++, it has been improved in each and every new standard of the language.

I'm a big fan of constexpr and am not alone. Jason Turner is also very vocal, having coined the term "constexpr all the things".

Well, demonstrating the powers of constexpr is nonetheless something difficult. I know that from my training classes and various consulting contracts. Today, I'd like to share a story from back in time when a customer hired me to consult. They did develop an embedded system and ran out of memory. Not during run-time, but before. The features they wanted to put in the chip were too big in code size and somewhat RAM.

Initial constexpr-free example

They used a class I've seen a couple of times in embedded systems with some variations. A string brings its memory picky-back. 

 

 

Reverse Iterations -- Coral Kashri

c-senioreas-v9.pngSometimes, we all need a way to iterate over a container in the opposite direction. There are several ways to reverse-iterate a container, and in this article, we’ll explore them.

Reverse Iterations

by Coral Kashri

From the article:

Probably the simplest way, taken from C is to iterate using an index location:
for (int64_t index = ssize(container); index >= 0; --index) {
    // do something with `container[index]`
}
This way is highly not recommended as it might lead to infinite loops if done incorrectly (for example by using uint64_t or size_t for the index type), and you can find more issues with this way in some previous articles about iterators in this blog.

C++26: user-generated static_assert messages -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGstatic_assert further evolves with C++26. Our tool for compile-time assertion will support user-generated error messages. As such, we’ll be able to reuse messages as well as enrich them with information available at compile-time making diagnostics easier to read.

C++26: user-generated static_assert messages

by Sandor Dargo

From the article:

Our first quest into the world of C++26 was about =delete with an optional error message, which improves the readability of the source code and potentially the error messages. In this next part of our journey, we will continue to focus on readability improvements, particularly those for error messages.

With C++26 and the acceptance of P2741R3, we are getting better error messages for static_assert. Compile time assertions were introduced in C++11 with a mandatory message. Since C++17, the message is only optional. And with C++26, static_assert evolves further and the message can be a constant expression instead of an unevaluated string. In other words, it can have some dynamic elements.

This was not the first attempt to make such a feature part of C++, but back in 2014, when something similar was proposed, C++ didn’t have enough compile-time programming capabilities to make this easily implementable.

Why is this change useful?

Before looking at some concrete examples of utilisation, let’s dig into the motivations behind this feature.

Obviously, we want better error messages. C++ is infamous for its horrendous error logs when the compilation fails. Even though we must admit that it’s more and more just a legacy, the situation improved a lot over the course of the years. In any case, it was mostly template-related error messages that were behind the biggest issues.

While compile-time assertions with their custom messages already meant an improvement, user-generated diagnostic messages will further improve the situation.

But that’s not the only motivation. Sometimes you don’t want different, or better messages. You just want the same message in several assertions without having to duplicate it. Without this change, the following piece of code doesn’t compile:

The first Meeting C++ trainings in 2025

With the success of the trainings after Meeting C++ 2024, I've decided to offer more opportunities for you to learn C++. Klaus Iglberger starts next week with C++ Software Design.

With these trainings following in March:

    Generic programming in C++ with templates and auto with Nicolai Josuttis (10th March, 1 day)
    Embedded C++ Basic Training with Richard Kaiser (10th March, 4 days)
    C++ Fundamentals You Wish You Had Known Earlier with Mateusz Pusz (13th March, 2 days)
    Concepts, Ranges, and Views - The New Way of Programming in C++ with Nicolai Josuttis (17th March, 1 day)
    Introduction to C++ - Five Day Online Training with Slobodan Dmitrovic (24th March, 5 days)
    Structured Concurrency in C++: A Hands-On Workshop (Coroutines + Senders/Receivers) with Mateusz Pusz (24th March, 2 days)

My goal is to offer a good set of trainings within a certain time frame each quarter with changing trainers. Ideally all within one week, but that doesn't match out all the time.

 

8 More C++23 Examples -- Bartlomiej Filipek

filipek-8moreexamples.pngIn this article, you’ll see eight larger examples that illustrate the changes in C++23.

8 More C++23 Examples

by Bartlomiej Filipek

From the article:

C++23 brings a ton of cool features, as you can see in my two previous articles (here and here). So far, we explored each new addition one by one, but I’d like to share more examples that combine multiple features.

Here we go:

1. std::ranges::to<> 

The ranges::to<> feature allows you to convert ranges into containers easily:

filipek-8examples.png

In C++, failure to meet the requirements does not always mean that you fail -- Raymond Chen

RaymondChen_5in-150x150.jpgWhen tasked with diagnosing why a pointer passed through a pipeline emerged offset from its original value, I discovered an interesting culprit: the misuse of a wrapper function around SubmitWork. While the wrapper aimed to simplify usage by allowing both raw pointers and references to standard layout types, it inadvertently caused ambiguous overload resolution, leading to incorrect behavior. This analysis explores how the issue arose, the debugging process, and improvements to ensure robust and predictable pointer handling in similar scenarios.

In C++, failure to meet the requirements does not always mean that you fail if you don’t meet the requirements

by Raymond Chen

From the article:

I was asked to help debug a problem where a pointer passed to a function was received slightly offset from the original value. The pointer is passed as an opaque parameter and is supposed to be spit out the other end of a pipeline. But somehow, the value that came out the other end was slightly different.

For expository purposes, let’s say that the underlying function we’re trying to call is this one.

void SubmitWork(HWORKER worker, int commandCode, void* param);

You call Submit­Work with a worker, a command code, and a raw pointer to some data that depends on the command code.

The developer sent me some debugging output that showed that the function that handled the command code received a different pointer from what was passed. One possibility is that there was a bug in the library that resulted in it unintentionally modifying the final pointer parameter, but this seemed unlikely, since the value should be opaque to the library. I was able to get on a video call with the developer to watch them step through the code, and that’s where I noticed something interesting.

 

ADL – Avoid Debugging Later -- Coral Kashri

kashri-adl.pngBack in the day, being a witch was considered a grave crime. Today, we’re diving into one of C++’s lesser-known spells: ADL (Argument-Dependent Lookup). 

ADL – Avoid Debugging Later

by Coral Kashri

From the article:

But before we explore this arcane magic, you must heed a warning—black magic comes with consequences. ADL is particularly treacherous, often leading to frustrating and hard-to-debug issues. Whenever possible, it’s wise to avoid casting this spell unless absolutely necessary.

Ingredients

Every spell needs ingredients, this time the only ingredients you need are a C++ compiler and a function that accepts at least one parameter, but there is a try catch, the parameter type has to belong to the same namespace of the function.

This spell works in shadows—you must look closely to uncover its effect.

std::cout << "Can you see me?";

Should the spell have passed you by, I’ll summon its power again for your eyes:

std::vector<int> a{1}, b{2};
swap(a, b);

If the spell’s effect remains elusive, let’s summon the entire code for you to see:

#include <vector>

int main() {
    std::vector<int> a{1}, b{2};
    swap(a, b);
    return 0;
}

21st Century C++ -- Bjarne Stroustrup

It is now 45+ years since C++ was first conceived. As planned, it evolved to meet challenges, but many developers use C++ as if it was still the previous millennium. This is suboptimal from the perspective of ease of expressing ideas, performance, reliability, and maintainability.

21st Century C++

by Bjarne Stroustrup

About the article:

Here, I present the key concepts on which performant, type safe, and flexible C++ software can be built: resource management, life-time management, error-handling, modularity, and generic programming. At the end, I present ways to ensure that code is contemporary, rather than relying on outdated, unsafe, and hard-to-maintain techniques: guidelines and profiles.

Serialization by contract -- Alex Marmer

Alex shows in his small framework a different approach for serialization of data structures.

Serialization by contract

By Alex Marmer

From the article:

In any project, when a function is created for serialization, another function is created for unserialization.

Serialization by contrast uses another approach - a contract with name and data structures is declared, and then serialization and unserialization of the data are automatic.

Contracts for C++ explained in 5 minutes -- Timur Doumler

In this article, we briefly explain everything you need to know to get started with Contracts as proposed for C++26 in P2900.

Contracts for C++ explained in 5 minutes

by Timur Doumler

From the article:

With P2900, we propose to add contract assertions to the C++ language. This proposal is in the final stages of wording review before being included in the draft Standard for C++26.

It has been suggested by some members of the C++ standard committee that this feature is too large, too complicated, and hard to teach. As it turns out, the opposite is true: contract assertions are actually very simple and can be explained in just five minutes. In this blog post, we will do exactly this!