C++ timebomb types aka Foot Gun with a Timer

Do not use static_assert to constrain the types you are developing. Huh?  What does that even mean? Why not?

One big foot gun. Ready to fire.

Currently using std:: well-known containers, to the surprise of many, one can create all sorts of timebomb types, and then someone else unknowingly and innocently might code all sorts of well-hidden timebombs, using those types.

We call them “timebombs”, because they might be unnoticed for months or even years and just then make your code not compile. Godbolt is here.

The key problem

static_assert does not constrain the creation of type, it does constrain the instantiation of a type.

Consider this example from one good and young c++ author.

timebomb_type is a derived type. timebomb type can be compiled, but no instances of that type can be ever made. Any attempt to do so will be stopped by the compiler.

Exactly the same timebomb “constraint” is adopted in (for example) MS STL.

To add the oil to that grill, the key issue is that timebomb_type can be used to create other types. That is because static_assert will “kick in” just when someone tries to instantiate the type. Not before. Few examples, with important info on the location of the offending code:

Above is what one might name “C++ sitcom”. Comey of errors no one is aware of.  And. There is more. Template instantiation anyone? We have that too.

Every compiler will obey and compile the above without a single grudge. Imagination is the only constraint (pun intended) here. All sorts of well-hidden timebombs and foot guns can be produced in standard C++ with no or very little warning from the compiler.

And no warning to the future unfortunate users carrying around third party code with timebomb types. Try it yourself in the Godbolt.

The simple remedy

Just a type constrained template is enough to stop wrong type definitions down the line. And you constrain the type with std::enable_if; in modern C++.

The outcome is, the user (or you) can not introduce types whose usage will not compile only a few months or years down the line.

This post describes a  peculiarity one might describe as “C++ foot gun with a timer” …

Bonus

Using C++20 and beyond, one can boldly use the “dreaded” constraints, everybody is afraid of. Here is one example  to try and convince you to look into the C++20  requires keyword:

Not that complicated. It looks quite clear actually.  If you try and create a “wrong” type from that template you will get much clearer error messages vs using the good old std::enable_if. Try.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: