Articles & Books

The Puzzle of Trying to Put an Object into a std::optional -- Raymond Chen

RaymondChen_5in-150x150.jpgThe std::optional<T> is a powerful tool for handling optional values, but assigning non-trivial types like Doodad to it can lead to unexpected compilation errors. This post explores why such assignments fail and unpacks the nuances of std::optional and type construction in modern C++.

The Puzzle of Trying to Put an Object into a std::optional

by Raymond Chen

From the article:

The C++ standard library template type std::optional<T> has one of two states. It could be empty (not contain anything), or it could contain a T.

Suppose you start with an empty std::optional<T>. How do you put a T into it?

One of my colleagues tried to do it in what seemed to be the most natural way: Use the assignment operator.

struct Doodad
{
    Doodad();
    ~Doodad();
    std::unique_ptr<DoodadStuff> m_stuff;
};

struct Widget
{
    std::optional<Doodad> m_doodad;

    Widget()
    {
        if (doodads_enabled()) {
            // I guess we need a Doodad too.
            Doodad d;
            m_doodad = d;
        }
    }
};

Unfortunately, the assignment failed to compile:

Implicit String Conversions to Booleans -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGIn this article, we'll learn about -Wstring-conversion, something I learned from C++ Brain Teasers by Anders Schau Knatten](https://www.sandordargo.com/blog/2024/10/16/cpp-brain-teasers). Clang offers this compiler warning which fires on implicit conversions from C-strings to bools.

Implicit String Conversions to Booleans

by Sandor Dargo

From the article:

Let’s start with the first part by explaining why such an implicit conversion is possible. A string literal is an array of const chars. Arrays can be converted into pointers, something we talked about last week when we discussed why spans are so useful. This is also called decay. Furthermore, pointers can be converted into booleans. That is how a string literal can be converted into a bool.

static_assert(!!"" == true);
static_assert(static_cast<bool>("") == true);

What might be surprising though is that even an empty string literal is converted into true. The reason is that only a nullptr would be converted into false, but an empty string literal is an array of a size of one so it’s not a nullptr. As a result, "" converted to true. The possible confusion is that the one character in that array of one is the \0 terminator. But this shouldn’t really matter. You shouldn’t use such shady implicit conversions.

We could end this article right here. But life is not ideal and I tried to turn on -Wstring-conversion in a production codebase where I found a few different cases of string literals conversions.

Around the World in C++: Exploring Time Zones with std::chrono -- Bartlomiej Filipek

2024-11-21_12-55-09.pngWhile most time zones use simple hour offsets from UTC, some regions have chosen unusual time differences. In this blog post, we’ll explore how we can discover such zones using C++20’s chrono library.

Around the World in C++: Exploring Time Zones with std::chrono

by Bartlomiej Filipek

From the article:

We’ll use GCC 14.2 as it fully supports C++20 chrono and also std::print from C++23.

First Attempt: Basic Zone Iteration

C++20 introduced comprehensive time zone support through the <chrono> library. The implementation relies on the IANA Time Zone Database (also known as the “tz database” or “zoneinfo”), which is the de facto standard for time zone information used by most operating systems and programming languages.

The Time Zone Database

In C++20, the time zone database is represented by the tzdb class:

2024-11-21_12-57-47.png

Use std::span Instead of C-style Arrays -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGC-style arrays are still used, mostly when you have to deal with C-libraries. They come with significant limitations, particularly when passed to functions where array decay occurs, leading to the loss of size information.

Use std::span Instead of C-style Arrays

by Sandor Dargo

From the article:

While reading the awesome book C++ Brain Teasers by Anders Schau Knatten, I realized it might be worth writing about spans.

std::span is a class template that was added to the standard library in C++20 and you’ll find it in the <span> header. A span is a non-owning object that refers to a contiguous sequence of objects with the first sequence element at position zero.

In its goal, a span is quite similar to a string_view. While a string_view is a non-owning view of string-like objects, a span is also a non-owning view for array-like objects where the stored elements occupy contiguous places in memory.

While it’s possible to use spans with vectors and arrays, most frequently it will be used with C-style arrays because a span gives you safe access to its elements and also to the size of the view, something that you don’t get with C-style arrays.

When and why does it come in handy?

C++ programmer's guide to undefined behavior: part 10 of 11

Your attention is invited to the tenth part of an e-book on undefined behavior. This is not a textbook, as it's intended for those who are already familiar with C++ programming. It's a kind of C++ programmer's guide to undefined behavior and to its most secret and exotic corners. The book was written by Dmitry Sviridkin and edited by Andrey Karpov.

C++ programmer's guide to undefined behavior: part 10 of 11

by Dmitry Sviridkin

From the article:

As you can see from the backtrace, the problematic object whose destructor caused the crash was a vector of strings in libgtest.so. In GTest sources, I found that this vector is a global variable where InitGoogleTest() stored recognized command line arguments. It's just a global variable declared in the compiled file and not presented in the header file. All seemed fine, except for one detail: it wasn't marked as static and was not wrapped in an anonymous namespace. So what? It worked, didn't it? Yeah, it worked. The trick was how the gMock library is built. Let's reproduce it step by step.

What is the Current Time Around the World? -- Bartlomiej Filipek

2024-11-21_12-48-43.pngIn this blog post, we will explore handling dates using std::chrono, including time zones. We’ll utilize the latest features of the library to retrieve the current time across various time zones, taking into account daylight saving time changes as well. Additionally, we will incorporate new capabilities introduced in C++23, such as enhanced printing functions and more.

What is the Current Time Around the World? Utilizing std::chrono with Time Zones in C++23

by Bartlomiej Filipek

From the article:

Let’s start with the following code that prints the current date and time:

#include <chrono>
#include <print>

int main() {
    auto now = std::chrono::system_clock::now();
    std::print("now is {}", now);
}

You can run it through Compiler Explorer

In my session, I’m getting the following results:

Now is 2024-11-01 11:44:06.374573703

Having Fun with Modern C++ -- Daniel Lemire

Jb7DBcxe_400x400.jpgRecent versions of the C++ language (C++20 and C++23) may allow you to change drastically how you program in C++. I want to provide some fun examples.

Having Fun with Modern C++

by Daniel Lemire

From the article:

Thanks to the integration of the features from the popular fmt library, it is much easier to format strings elegantly in C++. In turn the fmt library was inspired by the work done in languages like Python.

Suppose that you have a vector of integers and you want to print its content:

std::vector<int> v = {1, 2, 3, 4, 5};
std::println("{}", v);

Suppose you want it to be centered in a line of 40 characters, with underscore characters around it:

std::vector<int> v = {1, 2, 3, 4, 5};
std::println("{:_^40}", v);
// ____________[1, 2, 3, 4, 5]_____________

Trip Report: Meeting C++ 2024 -- Sandor Dargo

SANDOR_DARGO_ROUND.JPGLast week, I got the chance to go to Berlin and participate in the 10th edition of Meeting C++ which is as far as I know the biggest C++ conference in Europe. Considering both the online and onsite participants, there were about 500 of us, eager to learn more mostly but not only about C++.

Trip Report: Meeting C++ 2024

by Sandor Dargo

From the article:

The conference was held in the East side of Berlin, in the Vienna House by Wyndham Andel’s Berlin Hotel offering some cool views of the city from its higher floors, especially from its sky bar. Not that we had a lot of time wandering in Berlin, the schedule was quite packed. Although the program only started around 9-10 AM depending on the day, the first two days the official program didn’t end before 10 PM.

Given the bit cold and cloudy weather, I realized that Berlin in November is really perfect for a conference. People will not be tempted to escape the venue for long walks outside. It just feels better to be inside.

C++ Compile-Time Programming -- Wu Yongwei

logo.pngProgramming at compile time has been possible in C++ for a long time. Wu Yongwei considers its past, present and future.

Compile-time programming is a key feature of C++. It enables writing high-performance code often unattainable in other languages. This article explores its past, present, and future applications, highlighting the diverse possibilities in C++. We’ll briefly cover template metaprogramming, constexpr, variadic templates, static reflection, and more.

C++ Compile-Time Programming

by Wu Yongwei

From the article:

Compile-time programming is vastly different from run-time programming. The code runs during compilation, but the results can be used at run time.

Some believe compile-time programming is merely a trick, unused in real-world engineering. To them, I ask: do you use the C++ Standard Library? The mainstream implementations rely heavily on various programming techniques, including compile-time programming.

‘I don’t write the standard library’ – this might be a possible response. But consider this: the standard library is just one tool, a standard weapon. Is it enough to use only standard tools? That’s the real question.

The abundance of excellent open-source libraries suggests otherwise. A skilled programmer crafts tools for themselves and their team. If your work feels tedious, perhaps it’s time to build a bulldozer to tackle problems.

Compile-time programming offers a way to build such tools.

if constexpr requires requires { requires } -- Jonathan Müller

thinkcelllogo.pngProbably the two most useful features added to C++20 are requires and requires. They make it so much easier to control overload resolution, and when combined with if constexpr in C++17, they allow basic reflection-based optimizations in templates. While requires requires has gotten a lot of (negative?!) press for controlling overload resolution, its cousin requires { requires } is a bit overlooked.

if constexpr requires requires { requires }

by Jonathan Müller

From the article:

C++20 added requires, a way to enable or disable a function overload based on some compile-time condition. For example, consider a facility for producing debug output of types for error reporting:
thinkcellconst.png

The two overloads with the requires clause are only enabled for integers or floating point types, respectively, and are not considered otherwise. Additionally, overload resolution is smart: It knows that we want the overload with the most specific requirements, and it will only pick the first function when no other overload matches. This is also where concept comes in: A concept is simply a way to name a group of requirements that affects the search for more specific requirements. The technical term for that is subsumption. Because creating named requirements with concept also comes with additional syntax sugar, you don't need requires—so this blog post is gonna ignore concept. In general, if you would use a concept in only one place, it is too early to introduce it.