Articles & Books

Error on verge of extinction, or why I put if (x = 42) in Red List of C & C++ bugs

If we ask a programmer what bugs are the most common in C and C++ code, they'll name a null pointer dereference, undefined behavior, array overrun, and other typical error patterns. They may name an accidental assignment in condition as well. However, let's see if this error is common today.

Error on verge of extinction, or why I put if (x = 42) in Red List of C & C++ bugs

by Andrey Karpov

From the article:

Because of this bug, developers invented the Yoda notation: a programming style where the constant is placed on the left side of the comparison operator. This style was meant to prevent a typo. If a programmer writes = instead of ==, the code won't compile.

Adding State to the Update Notification Pattern, Part 6 -- Raymond Chen

RaymondChen_5in-150x150.jpgLast time, we built a stateful but coalescing update notification using a change counter to identify which request is the latest one, but noted that it does unnecessary work. Let’s see if we can avoid the unnecessary work.

Adding State to the Update Notification Pattern, Part 6

by Raymond Chen

From the article:

We could add some early exits to abandon the work if we notice that we are no longer doing work on behalf of the most recent text change. It means that we have to switch the change counter variable to a std::atomic since we will be reading the variable from the background thread at the same time the UI thread may be modifying it.

 
class EditControl
{
    ⟦ ... existing class members ... ⟧

    std::atomic<unsigned> m_latestId;
};

winrt::fire_and_forget
EditControl::TextChanged(std::string text)
{
    auto lifetime = get_strong();

    auto id = m_latestId.fetch_add(1, std::memory_order_relaxed);

    co_await winrt::resume_background();

    if (!IsLatestId(id))) co_return;

    std::vector<std::string> matches;
    for (auto&& candidate : FindCandidates(text)) {
        if (candidate.Verify()) {
            matches.push_back(candidate.Text());
        }
        if (!IsLatestId(id))) co_return;
    }

    co_await winrt::resume_foreground(Dispatcher());

    if (!IsLatestId(id))) co_return;

    SetAutocomplete(matches);
}

bool EditControl::IsLatestId(unsigned id) 
{ 
 return id == m_latestId.load(std::memory_order_relaxed);
} 

The background worker periodically checks whether its work has been discarded and abandons its efforts if so.

std::expected - Monadic Extensions -- Bartlomiej Filipek

BartlomiejFilipek-monadic.pngThe new std::expected feature from C++23 not only offers a robust error-handling mechanism but also introduces functional programming techniques like chaining operations with and_then, transforming results with transform, and managing errors using or_else and transform_error. This article explores these features, demonstrating how they can streamline your code by reducing redundant error checks while elegantly managing success and error states. Stay tuned as we dive into practical examples and see how these techniques are applied in real-world projects.

std::expected - Monadic Extensions

by Bartlomiej Filipek

From the article:

std::expected from C++23 not only serves as an error-handling mechanism but also introduces functional programming paradigms into the language. In this blog post, we’ll have a look at functional/monadic extensions of std::expected, which allow us to chain operations elegantly, handling errors at the same time. The techniques are very similar to std::optional extensions - see How to Use Monadic Operations for `std::optional` in C++23 - C++ Stories.

Here’s a brief overview of these functional capabilities:

and_then()
 
The and_then member function enables chaining operations that might produce a std::expected object. It’s invoked when the std::expected object holds a value and allows for seamless operation chaining without manual error checking after each step.
 

Adding State to the Update Notification Pattern, Part 5 -- Raymond Chen

RaymondChen_5in-150x150.jpgManaging stateful notifications is challenging when multiple requests arrive, and the goal is to only notify about the latest one. In the EditControl class, we use a counter to track the most recent request, updating it on the UI thread to ensure accurate ordering and prevent stale data from being processed. This approach works but is inefficient due to redundant calculations. Next time, we'll refine this strategy for greater efficiency.

Adding State to the Update Notification Pattern, Part 5 

by Raymond Chen

From the article:

We’ve been looking at the problem of a stateful but coalescing update notification, where multiple requests for work can arrive, and your only requirement is that you send a notification for the last one.

This time, we’ll apply the trick of using a counter to record who is doing the work on behalf of the most recent change. Here’s our first attempt:

 
class EditControl
{
    ⟦ ... existing class members ... ⟧

    unsigned m_latestId;
};

winrt::fire_and_forget
EditControl::TextChanged(std::string text)
{
    auto lifetime = get_strong();

    co_await winrt::resume_background();

    auto id = ++m_latestId;

    std::vector<std::string> matches;
    for (auto&& candidate : FindCandidates(text)) {
        if (candidate.Verify()) {
            matches.push_back(candidate.Text());
        }
    }

    co_await winrt::resume_foreground(Dispatcher());

    if (id != m_latestId) co_return;

    SetAutocomplete(matches);
}

Noisy: The Class You Wrote a Hundred Times -- Vincent Zalzal

OXUJNJk0_400x400.jpgYou have probably written a class that prints a message in all its special member functions. And like me, you probably wrote it multiple times. I decided to write it well once and for all, and share it.

Noisy: The Class You Wrote a Hundred Times

by Vincent Zalzal

From the article:

Recently, I was writing some code involving structured bindings and I was unsure whether it would incur unintended copy or move operations. As usual, when I am in this situation, I open up Compiler Explorer and test it. For the nth time, I ended up coding a class like this one:

struct S { 
S() { std::cout << "ctor\n"; } 
~S() { std::cout << "dtor\n"; } 
// ... and so on with copy and move operations 
}

I don’t know how many times I wrote this class! I thought maybe it was time I write it well, once and for all, and then reuse it when I need it. And then, I thought that I am probably not the only one having written that class over and over again, am I? Maybe this could be useful to others.

The Performance Impact of C++'s `final` Keyword -- Benjamin Summerton

book2_final_scene.pngIf you're writing C++, there's a good reason (maybe...) as to why you are. And probably, that reason is performance. So often when reading about the language you'll find all sorts of "performance tips and tricks" or "do this instead because it's more efficient". Sometimes you get a good explanation as to why you should. But more often than not, you won't find any hard numbers to back up that claim. I recently found a peculiar one, the final keyword.

The Performance Impact of C++'s `final` Keyword

by Benjamin Summerton

From the article:

Multiple blog posts claim that it can improve performance(sorry for linking a Medium article). It almost seems like it's almost free, and for a very measly change. After reading you'll notice something interesting: no one posted any metrics. Zero. Nada. Zilch. It essentially is "just trust me bro." Claims of performance improvements aren't worth salt unless you have the numbers to back it up. You also need to be able to reproduce the results. I've been guilty of this in the past (see a PR for Godot I made).

Being a good little engineer with a high performance C++ pet project, I really wanted to validate this claim.

Adding State to the Update Notification Pattern, Part 4 -- Raymond Chen

RaymondChen_5in-150x150.jpgIn our previous discussion, we explored the intricacies of stateful but coalescing update notifications, shedding light on the pivotal role of the UI thread in implicit serialization. However, what if this luxury of implicit synchronization is absent? Delving into an alternate version of our solution, we confront the looming specter of race conditions and the necessity for meticulous thread management to ensure seamless operation. Join us as we navigate the complexities of thread synchronization and embark on a quest to refine our approach to asynchronous work handling.  

Adding State to the Update Notification Pattern, Part 4

by Raymond Chen

From the article:

Last time, we developed a stateful but coalescing update notification, and we noted that the UI thread was doing a lot of heavy lifting. What if you don’t have a UI thread to do implicit serialization for you?

If there were no resume_foreground(Dispatcher()), we would have a race if a Text­Changed occurs after the worker has decided to exit, but before it has had a chance to mark itself as not busy. Here’s an alternate version that demonstrates the race.

Trip Report: Winter ISO C++ Meeting in Tokyo, Japan -- David Sankel

tokyoreport.pngAnother meeting, another slew of potential changes to standard C++. In this recap, I’ll summarize the working draft’s most significant changes, spotlight my favorite proposal at the meeting, Member customization points for Senders and Receivers, and discuss a handful of notable developments.

Trip Report: Winter ISO C++ Meeting in Tokyo, Japan

by David Sankel

From the article:

What’s new in the draft standard?

This snippet summarizes the notable changes:


	// wg21.link/p2573r2

	void newapi();

	void oldapi() = delete(“oldapi() is outdated, use newapi() instead”);

	

	void f() {

	    std::println(); // Shorthand for ‘std::println(“”)’. wg21.link/p3142r0

	

	    // Paths can be printed/formatted now. wg21.link/p2845r8

	    std::println(“Here’s a path: {}”,

	                 std::filesystem::path(“/stlab/chains”));

	

	    std::vector<int> x{1, 2, 3};

	    std::array<int,3> y{4, 5, 6};

	

	    // Outputs 1, 2, 3, 4, 5, and 6 separated by newlines.

	    for( auto i : std::views::concat(x, y) ) // concat is new from

	        std::cout << i << std::endl;         // wg21.link/p2542r8

	}

Adding State to the Update Notification Pattern, Part 3 -- Raymond Chen

RaymondChen_5in-150x150.jpgIn our continued exploration of efficient stateful update notifications, we delve into optimizing our existing solution to mitigate unnecessary background work. By introducing periodic checks for pending text and leveraging mutex protection, we aim to streamline the process and enhance performance. However, as we unravel these optimizations, we confront the complexities of managing thread safety and delve into the intricacies of background thread synchronization.

Adding State to the Update Notification Pattern, Part 3

by Raymond Chen

From the article:

Last time, we developed a stateful but coalescing update notification, and we noted that the code does a lot of unnecessary work because the worker thread calculates all the matches, even if the work has been superseded by another request.

We can add an optimization to abandon the background work if it notices that its efforts are going to waste: Periodically check whether there is any pending text. This will cost us a mutex, however, to protect access to m_pendingText from multiple threads.