When can the C++ compiler devirtualize a call?

Someone recently asked me about devirtualization optimizations: when do they happen? when can we rely on devirtualization? do different compilers do devirtualization differently? As usual, this led me down an experimental rabbit-hole. The answer seems to be: Modern compilers devirtualize calls to final methods pretty reliably. But there are many interesting corner cases — including some I haven’t thought of, I’m sure! — and different compilers do catch different subsets of those corner cases.

Read More

What are X-macros?

“X-macros” is a neat C and C++ technique that doesn’t get enough advertisement. Here’s the basic idea:

Suppose we have a table of similar records, each with the same schema. In games, this might be our collection of monster types (each with a display name, a representative icon, a dungeon level, a bitmask of special attack types, etc). In networking, this might be our collection of error codes (each with an integer value, a message string, etc).

We could encode that information into a data structure that we traverse at runtime to produce interesting effects — for example, an array of structs that we index into or loop over to answer a question like “What is the error string for this enumerator?” or “How many monsters have dungeon level 3?”.

But the “X-macros” technique is to encode that information in source code, which can be manipulated at compile time. We encode the information generically, without worrying about how it might be “stored” at runtime, because we’re not going to store it — it’s just source code! …

Read More

The Box of Delights

I’ve just finished reading John Masefield’s The Box of Delights (1935). I had picked it up at random in a tourist-trap gift shop several months ago, knowing only that it appeared vaguely Christmassy — not knowing at the time that it is (apparently) a giant of British Christmas pop culture, on par with The Nutcracker.

Read More

A better 404 polyglot

Between 2009-ish and 2018, StackOverflow’s 404 page displayed the following polyglot program:

# define v putchar
#   define print(x) ⏎
main(){v(4+v(v(52)-4));return 0;}/*
#>+++++++4+[>++++++<-]>⏎
++++.----.++++.*/
print(202*2);exit();
#define/*>.@*/exit()

This program was originally due to Mark Rushakoff, who later proposed a shorter version: …

Read More

The STL is more than std::accumulate

Conor Hoekstra gives great talks on algorithms. Notably, “Algorithm Intuition” (C++Now 2019) and “Better Algorithm Intuition” (code::dive 2019). However, every time I watch one of his talks where he uses STL algorithms to solve some programming problem, I come away feeling like

Let's see who's really under that mask! Why, it's old Mr. Accumulate and his brother For_each!

Let’s look at two examples of “using STL algorithms to solve problems” in this limited sense, and how else we might solve them. Both of these examples are taken from Conor’s CppCon 2020 talk “Structure and Interpretation of Computer Programs: SICP.”

Read More

“Flash of unstyled base class”

This week I ran into an interesting bug in the unit tests for some multithreaded code. The setup for the test involved a “process status daemon” that (in production) polled some global state once per second, and also provided some auxiliary functions that we wanted to test. The “once per second” code came from an old and widely-used internal helper library. In this retelling, I’ve taken the liberty of updating it for C++20:

Read More