Live and Let Die -- Martin Janzen

Resource lifetime management can be problematic. Martin Janzen reminds us how important destructors are and when to be mindful of their limitations.

Live and Let Die

By Martin Janzen

From the article:

Most experienced C++ programmers will agree that one of the best properties of our language is the ability to manage object lifecycles using constructors and destructors.

Bjarne Stroustrup [Stroustrup19] has described ctor/dtor pairs as one of C++’s most elegant features, giving us the ability to create clean types which tidy up after themselves, with predictable performance, minimal overhead, and no need for garbage collection.

In this year’s ACCU Conference Lightning Talks, Nico Josuttis singled out destructors as (spoiler alert!) “the most important C++ feature” [Josuttis23]; and Wiktor Klonowski told a sad tale of time wasted debugging a .NET program that kept running out of ports, a fate which could have been avoided by the use of dtors [Klonowski23].

At the same conference, as well as at the recent C++ On Sea, numerous speakers talked about C++ and safety, a subject that’s been very much in the news recently [NSA22], with C++ predictably receiving a lot of flak for the ease with which one can write code containing buffer overflows, memory leaks, and of course a rich and varied choice of ways to introduce undefined behaviour (UB).

In its favour, though, C++ also provides at least one way in which we can improve safety, and reliability, greatly, by use of the powerful RAII (Resource Acquisition is Initialisation) idiom: taking ownership of a resource in the ctor, then releasing it in the dtor.

Spans, string_view, and Ranges - Four View types (C++17 to C++23) -- Bartlomiej Filipek

spans_string_view.pngIn this blog post, we’ll look at several different view/reference types introduced in Modern C++. The first one is string_view added in C++17. C++20 brought std::span and ranges views. The last addition is std::mdspan from C++23.

Spans, string_view, and Ranges - Four View types (C++17 to C++23)

by Bartlomiej Filipek

From the article:

The std::string_view type is a non-owning reference to a string. It provides an object-oriented way to represent strings and substrings without the overhead of copying or allocation that comes with std::stringstd::string_view is especially handy in scenarios where temporary views are necessary, significantly improving the performance and expressiveness of string-handling code. The view object doesn’t allow modification of characters in the original string.
Here's a basic example:
#include <format>
#include <iostream>
#include <string_view>

void find_word(std::string_view text, std::string_view word) {

    size_t pos = text.find(word);
    if (pos != std::string_view::npos)
        std::cout << std::format("Word found at position: {}\n", pos);
    else
        std::cout << "Word not found\n";
}
	
int main() {

    std::string str = "The quick brown fox jumps over the lazy dog";
    std::string_view sv = str;

    find_word(sv, "quick");
    find_word(sv, "lazy");
    find_word(sv, "hello");

}

Microsoft Visual C++ at CppCon 2023 Trip Report -- Sinem Akinci

cppcon.pngThe Visual C++ team attended CppCon 2023, the largest in-person C++ conference, in Aurora, Colorado from October 2-6th. There were over 700 attendees from the C++ community, and we really enjoyed getting a chance to meet all of you and talk about your unique backgrounds and C++ experiences.

Microsoft Visual C++ at CppCon 2023 Trip Report

by Sinem Akinci

From the article:

Some of our team member’s talks are now available to watch on YouTube so that you can watch them even if you missed CppCon to learn the latest for our tooling and more:

The venue was at the Gaylord Rockies this year. The Gaylord Rockies is a resort with a massive convention center and many restaurants to go check out. Somehow, it still felt small, as we were constantly running into familiar C++ faces and meeting them in different areas in the convention center. There really is no experience like it.  

Faster Hash Maps, Binary Trees etc. Through Data Layout Modification -- Ivica Bogosavljević

2023-10-02_15-20-11.pngIn this post we talk about how data structure data layout effects software performance and how, by modifying it, we can speed up the access and modification of the data structure.

Faster Hash Maps, Binary Trees etc. Through Data Layout Modification

By Ivica Bogosavljević

From the article:

This post is a logical continuation of the previous post about class layout and performance, where we talked about how class size and class layout influences software performance.

The basic premises of good memory performance hold in this case as well:

  • Everything that is accessed together should be stored together. Otherwise, the memory subsystem needs to more resources to fetch data.
  • Exploite the cache line organization of the memory subsystem. Since data is brought in blocks of 64 bytes from the memory to the data caches, our programs should consume all of it.
  • Keep data compact in memory speeds up access and modification. Smaller data more easily fits in the faster parts of the memory subsystem.

Techniques

Different techniques apply for different data structures. But in essence, all techniques revolve around the same idea of making the logically neighboring data physically close as well.

Polymorphism and Vectors of Pointers

In C++, to use polymorphism, you need to access the object through a pointer or a reference. And to access a collection of polymorphic objects, you need a vector of pointers (or some other data structure that holds pointers). As a data structure, a vector of pointers has two problems:

  • For each pointed object there needs to be a call to a system allocator to allocate the memory for the objects.
  • To access an object, a pointer needs to be dereferenced.

Trip report: Autumn ISO C++ standards meeting (Kona, HI, USA) -- Herb Sutter

reflection.pngA report out from this week's ISO C++ standards committee meeting, which just ended:

Trip report: Autumn ISO C++ standards meeting (Kona, HI, USA)

by Herb Sutter

From the article:

This time, the committee adopted the next set of features for C++26. It also made significant progress on other features that are now expected to be complete in time for C++26 — including contracts and reflection.

2 Lines Of Code and 3 C++17 Features - The Overload Pattern -- Bartlomiej Filipek

2023-10-02_15-16-38.pngLearn how the overload pattern works for std::variant visitation and how it changed with C++20 and C++23.

2 Lines Of Code and 3 C++17 Features - The Overload Pattern

By Bartlomiej Filipek

From the article:

While I was doing research for my book and blog posts about C++17 several times, I stumbled upon this pattern for visitation of std::variant:

template<class... Ts> struct overload : Ts... { using Ts::operator()...; }; 
template<class... Ts> overload(Ts...) -> overload<Ts...>; 

With the above pattern, you can provide separate lambdas “in-place” for visitation.

It’s just two lines of compact C++ code but packs some exciting techniques.

Let’s see how this works and go through the three new C++17 features that make this pattern possible.

Changelog

  • Updated on 18th Septeber 2023: C++23 updates, and Compiler Explorer examples.
  • Updated on 13th January 2020: better description for the whole article and C++ 20 features were mentioned - CTAD for aggregates.
  • Initial version on 11th Feb 2019

Intro

The code mentioned at the top of the article forms a pattern called overload (or sometimes overloaded), and it’s primarily valid for std::variant visitation.

Intro to C++ Coroutines: Concept -- Ilya Doroshenko

Coroutine.pngThe time has come, fellow devs. We are on our way to uncover the newest concept of C++ language – Coroutines.

Intro to C++ Coroutines: Concept

By Ilya Doroshenko

From the article:

The newest concept of C++ language, Coroutines, is already used by several programming languages, like

  • C# async tasks and yield iterables, forming LINQ base;
  • JS with awaitables, replacing the old way of making consecutive calls, that was hard to understand did a lot of code identation for cases that required a lot of async execution;
  • Python with synchronous generator
  • etc.

They were introduced in the recent C++20 standard. However, instead of handy classes such as Task<> and std::generator<> we received a complex and low-level toolkit to make our own promises and futures. Only C++23 gave us our first usable coroutine type (std::generator<>). It seems like the C++ committee followed the quote: “give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime”.

Today we will discuss what is needed to understand coroutines, and in the later chapters we will make our own little coroutine.