Articles & Books

Subtle C++ Compiler Error with std::optional and the Conditional Operator -- Giovanni Dicanio

An example of writing clear code with good intention, but getting an unexpected C++ compiler error:

Subtle C++ Compiler Error with std::optional and the Conditional Operator

by Giovanni Dicanio

From the article:

I was asked: “What’s the problem here? Are there limitations of using the {} syntax to specify nothing?”

This is a good question. So, clearly, the C++ compiler didn’t interpret the {} syntax as a way to default-initialize the std::optional in case the string was not empty (i.e. the second “branch” in the conditional ternary operator).

A first step to help the C++ compiler figuring out the programmer’s intention could be to be more explicit. So, instead of using {}, you can try and use the std::nullopt constant, which represents an optional that doesn’t store any value. [...]

[...]

P.S. I’m not a C++ “language lawyer”, but it would be great if the C++ language could be extended to allow the original simple code to just work.

IEEE Floating Point and the Radar Range Equation in C++ -- John Farrier

The implementation of mathematical equations demands a keen awareness of the computational environment. This article uses a practical example of implementing the Radar Range Equation, a cornerstone formula in radar technology, to illustrate the importance of considering IEEE floating point representation in C++ for accurate and reliable computations.

Engineering Mathematics: A Focus on IEEE Floating Point and the Radar Range Equation in C++

by John Farrier

From the Article:

The nature of IEEE floating-point numbers in C++ brings certain challenges, especially when dealing with large or small numbers and operations like multiplication and division. Precision issues can significantly impact the accuracy of computations, making it essential to adapt the implementation strategy.

 

The Double Life of Objects -- Andrzej Krzemieński

doublelife-1.pngIn the world of C++, the concept of object lifetime and constness can become a bit hazy when copy elision, a popular optimization technique, comes into play. In this article, Andrzej Krzemieński explores the intricacies of object lifetimes and constness, using a class called Rng to illustrate how objects can appear const in one context and non-const in another due to copy elision. He'll also delve into the motivations behind C++'s handling of const objects and how it impacts program behavior.

The Double Life of Objects

by Andrzej Krzemieński

From the article:

Some common knowledge: the lifetime of the object starts when its initialization is complete. Based on this we can get some further expectations: an object becomes const only after its initialization is complete. But this lifetime property of objects becomes blurred when copy elision comes into play. When a copy is elided, we have a situation where we would otherwise have two objects, each initialized separately, but now they are blended into one, its life time spanning across the caller and the calle, which has a number of surprising effects, receiving two initializations being one of them.

In the following examples we will use class Rng that is quite small but convincing: you define a class when you need to maintain the invariant. Our class represents a range of integers between the minimum and maximum values.

doublelife-1.png

Now, let’s try to use it in a somewhat artificial program:

doublelife-2.png

Use SIMD: Save The Planet -- Andrew Drakeford

simddrake.pngWriting efficient code is challenging but worthwhile. Andrew Drakeford demonstrates how SIMD (Single Instruction Multiple Data) can reduce your carbon footprint.

Use SIMD: Save The Planet

by Andrew Drakeford

From the article:

Some sources claim that data centres consumed 2.9% of the world’s electricity in 2021 [Andrae15]. With the recent sharp increase in energy prices, many firms became aware of this cost. Additionally, trends in AI use and the near-exponential growth in both network and data services projected over the next few years [Jones18] suggest that this situation will only get worse.

A data centre’s single purpose is to run our software (not heat the planet). But what if the processing cores that our software runs on have a unique, often unused, feature that would enable them to do the work several times faster? Would this also mean several times more efficiently? This feature is SIMD (Single Instruction Multiple Data).

SIMD is a parallel computing technology that allows processors to perform the same operation on multiple data elements simultaneously. By using SIMD instructions, a single CPU instruction can operate on multiple data elements in a single clock cycle. For example, with 256-bit SIMD registers, it is possible to process eight 32-bit floating-point numbers or sixteen 16-bit integers in parallel. This leverages the data-level parallelism inherent in many algorithms, such as mathematical computations, image processing, audio processing, and simulations. Figure 1 illustrates the element-wise addition of two sets of numbers using the SSE2, AVX2 and AVX512 instructions sets.


 

SIMD instructions use vector registers, which can hold multiple data elements. These registers allow the CPU to apply a single instruction to all the elements simultaneously, thus reducing the instruction count. Consequently, SIMD can provide a substantial speedup for tasks that exhibit regular and parallelizable data processing patterns.

Six Handy Operations for String Processing in C++20/23 -- Bartlomiej Filipek

sixhandy-barto.pngIn this article, we’ll explore six practical string processing operations introduced in C++20 and C++23. These features represent an evolution in this crucial area, covering a spectrum of operations from searching and appending to creation and stream handling.

Six Handy Operations for String Processing in C++20/23

by Bartlomiej Filipek

From the article:

Let’s start with a simple yet long-awaited feature…

1. contains(), C++23

Finally, after decades of standardization, we have a super easy way to check if there’s one string inside the other. No need to use .find(str) != npos!

Before C++23:

sixhandy-1.png

And now, thanks to the proposal: P1679R3:
sixhandy-2.png
As you can see, the new approach with contains() is more straightforward and intuitive.

How to Print Unicode Text to the Windows Console in C++ -- Giovanni Dicanio

Have you ever wondered how to correctly print Unicode text to the Windows console in your C++ programs? Maybe you tried something, and you got meaningless output, or even an assertion failure at runtime, pointing to some obscure code in the CRT? Well, then this article is for you!

How to Print Unicode Text to the Windows Console in C++

by Giovanni Dicanio

From the blog post:

Suppose that you want to print out some Unicode text to the Windows console. From a simple C++ console application created in Visual Studio, you may try this line of code inside main:

std::wcout << L"Japan written in Japanese: x65e5x672c (Nihon)n";

As you can see, the Japanese kanjis are not printed. Moreover, even the “standard ASCII” characters following those (i.e.: “(Nihon)”) are missing. There’s clearly a bug in the above code.

How can you fix that?

Well, the missing piece is ...

Breaking Down C++20 Callable Concepts -- John Farrier

Learn about C++20's Callable Concepts, how they improve on SFINAE, and how to use them in your own code.

Breaking Down C++20 Callable Concepts

By John Farrier

From the article:

C++20 Callable Concepts refer to a powerful feature introduced in the C++20 standard that allows developers to specify and enforce constraints on function objects, lambdas, and other callable entities in a more expressive and type-safe manner. Callable Concepts enable the compiler to check if a given callable meets specific requirements, such as having certain member functions or satisfying particular type traits, before allowing it to be used in a template or function. This helps improve code readability, maintainability, and error detection, as it provides clearer and more structured ways to define the expected behavior and capabilities of callables in C++ code.

 

Easily Protect Your C++ Code Against Integer Overflow With SafeInt -- by Giovanni Dicanio

Integer overflows can be hidden inside your C++ code and can cause subtle nasty bugs.

Fortunately, it's easy to guard your code against those subtle bugs, thanks to an open-source easy-to-use library:

Protecting Your C++ Code Against Integer Overflow Made Easy by SafeInt

by Giovanni Dicanio

From the article:

In previous blog posts I discussed the problem of integer overflow and some subtle bugs that can be caused by that. (...)

Of course, writing this kind of complicated check code each time there is a sum operation that could potentially overflow would be excruciatingly cumbersome, and bug prone! (...)

Fortunately, you don’t have to do all that work! In fact, there is an open source library that does exactly that! This library is called SafeInt. (...)

The code will still look nice and simple, but safety checks will happen automatically under the hood. Thank you very much SafeInt and C++ operator overloading!