Articles & Books

AddressSanitizer continue_on_error -- Jim Radigan

jim-300x300.jpgVisual Studio 17.6 comes with new functionality in the Address Sanitizer runtime which provides a new “checked build” for C and C++. This new runtime mode diagnoses and reports hidden memory safety errors, with zero false positives, as your app runs.

AddressSanitizer continue_on_error

by Jim Radigan

From the article:

C++ memory safety errors are a top concern for the industry. In Visual Studio 17.6, we deliver a new experimental Address Sanitizer feature: continue_on_error (COE). We’ll remove the experimental label in 17.8. You compile as before, by simply adding the compiler flag -fsanitizer=address. With 17.6 you can enable the COE functionality by setting environment variables from the command line.

Monitor Object -- Rainer Grimm

concurrentarchitecture-grimm.pngThe Monitor Object design pattern synchronizes concurrent member function execution to ensure that only one member function runs within an object at a time. It also allows an object's member functions to schedule their execution sequences cooperatively.

Monitor Object

by Rainer Grimm

From the article:

Problem

If many threads access a shared object concurrently, the following challenges exist.

  • Due to the concurrent access, the shared object must be protected from non-synchronized read and write operations to avoid data races.
  • The necessary synchronization should be part of the implementation, not the interface.
  • When a thread is done with the shared object, a notification should be triggered so the next thread can use the shared object. This mechanism helps avoid and improves the system's overall performance.
  • After the execution of a member function, the invariants of the shared object must hold.

Solution

A client (thread) can access the Monitor Object's synchronized member functions, and due to the monitor lock, only one synchronized member function can run at any given time. Each Monitor Object has a monitor condition that notifies the waiting clients.

 

Finite State Machine with std::variant -- Bartlomiej Filipek

In this blog post, I’ll show you how to convert a “regular” enum-style finite state machine into a modern version based on std::variant from C++17. This technique allows you to improve design, work with value types and enhance code quality.

Finite State Machine with std::variant

by Bartlomiej Filipek

From the article:

Let’s start with a basic example:

  • we want to track a game player’s health status
  • we’d like to respond to events like “Hit by a monster” or “Healing bonus.”
  • when the health point goes to 0, then we have to restart the game only if there are some remaining lives available

Here’s a basic diagram with states and transitions:

New C++ Features in GCC13 -- Marek Polacek

newfeaturesc23.pngThe latest major version of the GNU Compiler Collection (GCC), 13.1, was released in April 2023. Like every major GCC release, this version brings many additions, improvements, bug fixes, and new features.

New C++ features in GCC 13

by Marek Polacek

 

From the article:

Like the article I wrote about GCC 10 and GCC 12, this article describes only new features implemented in the C++ front end; it does not discuss developments in the C++ language itself. Interesting changes in the standard C++ library that comes with GCC 13 are described in a separate blog post: New C features in GCC 13

Active Object -- Rainer Grimm

grimm-activeobject.pngThe active object design pattern decouples method execution from method invocation for objects that each reside in their own thread of control.The goal is to introduce concurrency, by using asynchronous method invocation and a scheduler for handling requests.

Active Object

by Rainer Grimm

From the article:

The Active Object decouples method invocation from method execution. The method invocation is performed on the client thread, but the method execution is on the Active Object. The Active Object has its thread and a list of method request objects (short request) to be executed. The client’s method invocation enqueues the requests on the Active Object’s list. The requests are dispatched to the servant.

When many threads access a shared object synchronized, the following challenges must be solved:

  • A thread invoking a processing-intensive member function should not block the other threads invoking the same object for too long.
  • It should be easy to synchronize access to a shared object.
  • The concurrency characteristics of the executed requests should be adaptable to the concrete hardware and software.

Solving Undefined Behavior in Factories with constinit from C++20 -- Bartlomiej Filipek

ub_constinit.pngA few years ago, I showed an interesting implementation for self-registering classes in factories. It works, but one step might be at the edge of Undefined behavior. Fortunately, with C++20, its new constinit keyword, we can update the code and ensure it’s super safe.

Solving Undefined Behavior in Factories with constinit from C++20

by Bartlomiej Filipek

From the article:

Let’s bring back the topic:

Here’s a typical factory function. It creates unique_ptr with ZipCompression or BZCompression based on the passed name/filename:

Here are some issues with this approach:

  • Each time you write a new class, and you want to include it in the factory, you have to add another if in the Create() method. Easy to forget in a complex system.
  • All the types must be known to the factory.
  • In Create(), we arbitrarily used strings to represent types. Such representation is only visible in that single method. What if you’d like to use it somewhere else? Strings might be easily misspelled, especially if you have several places where they are compared.

All in all, we get a strong dependency between the factory and the classes.

But what if classes could register themselves? Would that help?

The Move Constructor That You Have to Declare, Even Though You Don’t ... -- Raymond Chen

RaymondChen_5in-150x150.jpgYou may have a class that you want to participate in RVO or NRVO, but you also don’t want it to be moved. For example, it may contain a std::mutex, which is not movable. But you nevertheless have to declare a move constructor. What can you do?

The Move Constructor That You Have to Declare, Even Though You Don’t Want Anyone to Actually Call It

by Raymond Chen

From the article:

Blah blah blah C++ return value optimization (RVO), named return value optimization (NRVO), and copy elision.

RVO support was optional in C++11 but became mandatory in C++17. NRVO support remains optional (but recommended).

To allow NRVO in C++17 (or RVO and NRVO in C++11), a move constructor must be available, even though the compiler will not call it if the optimization is employed.

You may have a class that you want to participate in RVO or NRVO, but you also don’t want it to be moved. For example, it may contain a std::mutex, which is not movable. But you nevertheless have to declare a move constructor. What can you do?

Declare the move constructor, but...

Need Something Sorted? Sleep On It! -- Kevlin Henney

kevlinhenney.jpgSorting algorithms have been thoroughly studied. Kevlin Henney takes an unexpected paradigm journey into sleep sort.

Need Something Sorted? Sleep On It!

by Kevlin Henney

From the article:

A decade ago, I first presented a lightning talk entitled ‘Cool Code’. This short talk evolved into a full talk whose iterations I presented over the next half decade. The focus? Code that, for some reason or other, can be considered cool. For example, code that has played a significant role in historical events, such as the source for the Apollo Guidance Computer [Apollo]. Or code that is audacious – if not seemingly impossible – given its constraints, such as David Horne’s 1K chess [Frogley01]. There is code that is both simple and profound, such as Peter Norvig’s fits-on-a-slide spelling corrector [Norvig16]. And code that demonstrates ingenuity and humour, such as Yusuke Endoh’s Qlobe [Endoh10].

Leaving aside its content for a moment, one of the most interesting things about the talk was its...

Why You Should Only Rarely Use std::move -- Andreas Fertig

andreas-fertig.pngstd::move can allow the efficient transfer of resources from object to to object. Andreas Fertig reminds us that using std::move inappropriately can make code less efficient.

Why You Should Only Rarely Use std::move

by Andreas Fertig

From the article:

The example in Listing 1 is the code I used to make my point: don’t use std::move on temporaries! Plus, in general, trust the compiler and only use std::move rarely. For this article, let’s focus on the example code.

class S {
public:
  S() { printf("default constructor\n"); }
  ~S() { printf("deconstructor\n"); }
  // Copy constructor ①
  S(const S&) { printf("copy constructor\n"); }
  // Move constructor ②
  S(S&&) { printf("move constructor\n"); }
};
void Use()
{
  S obj{
    S{} // Creating obj with a temporary of S ③
  };
}
Listing 1

Here we see a, well, perfectly movable class. I left the assignment operations out. They are not relevant. Aside from the constructor and destructor, we see in ① the copy constructor and in ② the move constructor. All special members print a message to identify them when they are called.

Further down in Use, we see ③, a temporary object of S used to initialize obj, also of type S. This is the typical situation where move semantics excels over a copy (assuming the class in question has movable members). The output I expect, and I wanted to show my participants, is: