WHAT—
https://andreasjhkarlsson.github.io//jekyll/update/2023/12/27/4-billion-if-statements.html
4 billion if statements
I recently stumbled upon this screenshot while researching social media on the train. Of course, it was followed by a cascade of spiteful comments, criticizing this fresh programmer’s attempt to solve a classical problem in computer science.Blabbin’
Roufnichan LeGauf 🌈
in reply to Charlie Stross • • •To demonstrate the power of C++, I have reimplemented the algorithm in a single file using the built-in metaprogramming capabilities of C++. No more manual source generation; no more Python!
Compiler explorer: https://godbolt.org/z/434bPMP3M
To generate the comparisons, we use template metaprogramming. However, there are no template loops. C++ templates can be classified as an esoteric purely functional programming language, so we have to use pattern matching and recursion.
The
do_check<N>
template generates comparisons up to N. Our base case isdo_check<0>
, which compares to 0 and does nothing else. The general (inductive) case callsdo_check<N - 1>
and then compares to N.It is interesting to look at the generated code. G++ translates the algorithm faithfully, if slightly chaotically (look at the order of labels and comparisons in the source; it jumps all over the place). Clang, on the other hand, implements one of the optimizations suggested by @gkemp. It fills a big array with messages (
messages[256] = { "even", "odd", "even", "odd", ... }
) and then outputsmessages[n]
(there is only a single call toputs
in the generated assembler code).This covers numbers from 0 to 255 (the range of
uint8_t
). We can extend the range by switching tousing T = uint16_t
, although doing so naively runs into the following error:Fortunately it tells us how to fix it and with
g++ -ftemplate-depth=65536
we are right back in business. Well, after waiting 2½ minutes for the compilation to finish, that is. (Clang is less fortunate: It crashes with a segmentation fault after exhausting the available stack space, at least on Compiler Explorer.)I haven't dared try
T = uint32_t
yet.#CPlusPlus #templates
Compiler Explorer - C++
godbolt.org