Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do all C++ compilers crash or hang from this code?

The following bit of code crashes or hangs until memory exhaustion when compiled by every C++ compiler I've tested:

#include <tuple>

template<class... Ts>
auto f(Ts... ts){
  return f(std::make_tuple(ts...)); 
}

auto a = f();

Tested on various versions of GCC, Clang, MSVC, icc, ELLCC: https://godbolt.org/z/cwqiZK


My question is why is this not caught by template depth limits or similar safeties that these compilers implement? I found some examples of code, like this old example, that cause compilers to hang, but it seems like all of the issues I could find have been fixed since it became standard to limit template instantiation depth.

I should note that this is not unique to make_tuple, and works for tie, forward_as_tuple... etc.


As a warning, if you try to compile this locally, be sure to use something like ulimit to make sure the compiler does not exhaust your memory. I had to hard reboot a couple of times while playing around with this.

like image 590
Jeffrey Cash Avatar asked Feb 20 '20 21:02

Jeffrey Cash


People also ask

Why are there multiple C compilers?

There are over 50 compilers for C like ICC by Intel to GNU GCC by GNU Project. The focus of having multiple compilers is to optimize the compiled C code for specific hardware and software environments. This has lead to a vast number of compilers but some have been abandoned in the path.

Do C++ compilers work for C?

If the C++ compiler provides its own versions of the C headers, the versions of those headers used by the C compiler must be compatible. Oracle Developer Studio C and C++ compilers use compatible headers, and use the same C runtime library. They are fully compatible.

Does C++ compile down to C?

C++ compilers generate machine code in almost exactly the same way that C compilers do.

What happens when C++ code is compiled?

Compilation & assembly First, the compiler converts the pure C++ code, now stripped of preprocessor directives, into low-level assembly code. In this parsing step, the compiler optimizes the source code by pointing out syntax errors, overload resolution errors and any other compile-time errors.


1 Answers

GCC doesn't implement all possible variadic function template recursion detection methods (or possibly not any?), probably due to a variation of the concerns raised in the comments.

The OP example looks very similar (identical?) to GCC bug 59914 from 2014 that is unresolved. It looks like preventing these kinds of mistakes, or actually - preventing these kinds of mistakes from exploding all over a developer's workstation - is not a high priority for GCC developers. BTW - the example program reported in the bug abuses memory much faster than the OP: with an 800MB data limit, I can get the OP to do more than 150 template instantiations while the program in the bug report runs out of memory after less than 20.

Both programs also crash clang, so I guess the clang devs have similar priorities.

like image 114
Guss Avatar answered Nov 09 '22 23:11

Guss