advanced

Zero-cost exceptions aren’t actually zero cost--Raymond Chen

The devil is in the details.

Zero-cost exceptions aren’t actually zero cost

by Raymond Chen

From the article:

There are two common models for exception handling in C++. One is by updating some program state whenever there is a change to the list of things that need to be done when an exception occurs, say, because a new exception handler is in scope or has exited scope, or to add or remove a destructor from the list of things to execute during unwinding. Another model is to use metadata to describe what to do if an exception occurs. There is no explicit management of the state changes at runtime; instead, the exception machinery infers the state by looking at the program counter and consulting the metadata...

On finding the average of two unsigned integers without overflow--Raymond Chen

How did you solve it?

On finding the average of two unsigned integers without overflow

by Raymond Chen

From the article:

Finding the average of two unsigned integers, rounding toward zero, sounds easy:

unsigned average(unsigned a, unsigned b)
{
    return (a + b) / 2;
}

However, this gives the wrong answer in the face of integer overflow: For example, if unsigned integers are 32 bits wide, then it says that average(0x80000000U, 0x80000000U) is zero...

The Usual Arithmetic Confusions--Shafik Yaghmour

Do you know the conversions?

The Usual Arithmetic Confusions

by Shafik Yaghmour

From the article:

There are a lot of aspects of C++ that are not well understood and lead to all sorts of confusion. The usual arithmetic conversions and the integral promotions are two such aspects. Certain binary operators (arithmetic, relational and spaceship) require their operands to have a common type. The usual arithmetic conversions are the set of steps that gets operands to a common type. While the integral promotions brings integral types smaller than int and unsigned int to either int or unsigned int depending on which one can represent all the values of the source type. This is one of the areas in C++ that comes directly from C, so pretty much all of these examples applies to C as well as C++...

Conditional Members--Barry Revzin

Did you feel the need?

Conditional Members

by Barry Revzin

From the article:

I’d previously written a post about if constexpr (and how it’s not broken). I argued in that post how, broadly speaking, C++20 gives you the tools to solve the problems you want, even if they work a bit differently to D’s static if (with one notable exception, which this post greatly expands on). Now, over the past couple years, I’ve been working on a project that really is a deep dive into what Andrei calls “Design by Introspection.” This approach (for lack of a better definition), relies on conditioning functionality based on template parameters...

Transrangers: An Efficient, Composable Design Pattern for Range Processing -- Joaquín M López Muñoz

Another twist on ranges.

Transrangers: An Efficient, Composable Design Pattern for Range Processing

by Joaquín M López Muñoz

From the article:

Transrangers are a new design pattern for efficient, composable range processing that can be faster than pull-based C++/Range-v3 views whithout losing any expressiveness. The underlying architecture combines ideas from push processing with the internalization of control flow. Transrangers can be used on their own or be leveraged as an implementation detail of range libraries to improve the performance of view-based operations.

 

How C++ Resolves a Function Call--Jeff Preshing

Know everything about it.

How C++ Resolves a Function Call

by Jeff Preshing

from the article:

C is a simple language. You’re only allowed to have one function with each name. C++, on the other hand, gives you much more flexibility:

  • You can have multiple functions with the same name (overloading).
  • You can overload built-in operators like + and ==.
  • You can write function templates.
  • Namespaces help you avoid naming conflicts.

I like these C++ features. With these features, you can make str1 + str2 return the concatenation of two strings. You can have a pair of 2D points, and another pair of 3D points, and overload dot(a, b) to work with either type. You can have a bunch of array-like classes and write a single sort function template that works with all of them.

But when you take advantage of these features, it’s easy to push things too far. At some point, the compiler might unexpectedly reject your code with errors like:

error C2666: 'String::operator ==': 2 overloads have similar conversions
note: could be 'bool String::operator ==(const String &) const'
note: or       'built-in C++ operator==(const char *, const char *)'
note: while trying to match the argument list '(const String, const char *)'

Like many C++ programmers, I’ve struggled with such errors throughout my career. Each time it happened, I would usually scratch my head, search online for a better understanding, then change the code until it compiled. But more recently, while developing a new runtime library for Plywood, I was thwarted by such errors over and over again. It became clear that despite all my previous experience with C++, something was missing from my understanding and I didn’t know what it was.

Fortunately, it’s now 2021 and information about C++ is more comprehensive than ever. Thanks especially to cppreference.com, I now know what was missing from my understanding: a clear picture of the hidden algorithm that runs for every function call at compile time.

Parameter Passing in C and C++--Scott Wolchok

Let's go down to the metal.

Parameter Passing in C and C++

by Scott Wolchok

From the article:

Now that we know how to read assembly language, we can talk about how parameter passing works at the machine level and its consequences for writing faster code. We will focus on x86_64, but ARM64 works in a roughly similar way...