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.
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.
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.
C++ compilers generate machine code in almost exactly the same way that C compilers do.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With