The Case of Willie the Wisp

As a kid, I’d sometimes read a story where one line has stuck with me over the years as the perfect expression of some archetype. I find myself wishing that other people knew these same stories, so that I could actually use these lovely shorthands.

Read More

Folding over operator=

Jonathan Müller posted a “Nifty Fold Expression Trick” the other day:

template<class F, class... Ts>
void reverse_for_each(F f, Ts... ts) {
    int dummy;
    (dummy = ... = (f(ts), 0));
}

For example, reverse_for_each(putchar, 'a', 'b', 'c') prints cba.

However, as I puzzled out each step of the process, I realized that there were several subtleties to this “simple” expression! …

Read More

Connect Fifteen

Here’s a simple two-player card game you can play while stuck at home. I invented it sometime before 2003 — I would guess circa 1999. I call it “Connect Fifteen.”

Read More

Default function arguments are the devil

If you frequently talk with me about C++, you have undoubtedly heard me say:

Default function arguments are the devil.

My position opposes the historical (early-1990s) style of the STL, of course; but I was recently alerted that it’s also in direct conflict with the (2010s) C++ Core Guidelines, specifically rule F.51. Since this conflict might, if unaddressed, lead people to think I’m wrong, I’d better address it. ;) …

Read More

A seasonal followup to “When is *x also &x?”

Yesterday I wrote:

  • Teach the logic behind C-style declarations. int *p can mean “p is an int*,” and it can equally well mean “*p is an int.” int const *f() can mean “You aren’t allowed to modify the int,” or it can equally well mean “You aren’t allowed to modify *f().” (Of course this only works for pointers, not references; that’s another reason it’s important to reveal pointers early.)

In the Reddit comments, commenter “redditsoaddicting” pointed out that this logic even works for multiple declarations on the same line:

In int *p, q;, the expression *p, q is of type int.

Not only that, but after const int& x(), *y;, we find that decltype(x(), *y) is const int&! …

Read More

Ways C++ prevents you from doing X

C++ has many orthogonal ways of preventing you from doing what you asked for. When I’m doing training courses, I often find students confused (without necessarily knowing they’re confused) between these various failure modes. So I thought I’d write down the most common ones in a blog post.

Read More

The Design of Everyday Things

Today I re-read Don Norman’s 1988 book The Design of Everyday Things. I continue to highly recommend it to anyone who does engineering (especially software engineering). In particular, it’s the book that introduced me to the term affordances, as in “glass affords seeing-through, and breaking; a flat panel affords pushing but not pulling.” I felt like the term started to break out into the mainstream C++ community at CppCon 2019, what with its forming the core of my “Back to Basics: Type Erasure” and also being name-dropped by Titus Winters in the B2B track’s closing keynote “What is C++?”

Read More

Field-testing “Down with lifetime extension!”

I hacked my local Clang to produce a warning every time Sema::checkInitializerLifetime detected that lifetime extension was necessary.

test.cc:31:16: warning: binding temporary of type 'int' to a reference
relies on lifetime extension [-Wlifetime-extension]
    const int& i2 = 42;
                    ^~

Then I ran it over the LLVM codebase by rebuilding Clang with itself (“How to build LLVM from source, monorepo version” (2019-11-09)). Here’s what I found. …

Read More