[mostly copied from a thread on stackoverflow at http://stackoverflow.com/questions/37260097] This code takes several seconds to compile and produces a 52,776 byte executable: #include <array> #include <iostream> int main() { constexpr std::size_t size = 4096; struct S { float f; S() : f(0.0f) {} }; std::array<S, size> a = {}; // <-- note aggregate initialization for (auto& e : a) std::cerr << e.f; return 0; } Increasing 'size' seems to increase compilation time and executable size linearly. I cannot reproduce this behaviour with either clang 3.5 or Visual C++ 2015. Using -Os makes no difference. I've reproduced this on g++ 4.9.2 and 5.3.1, but 6.1 also seems to do the same thing. $ time g++ -O2 -std=c++11 test.cpp real 0m4.178s user 0m4.060s sys 0m0.068s Inspecting the assembly code reveals that the initialization of 'a' is unrolled, generating 4096 movl instructions: main: .LFB1313: .cfi_startproc pushq %rbx .cfi_def_cfa_offset 16 .cfi_offset 3, -16 subq $16384, %rsp .cfi_def_cfa_offset 16400 movl $0x00000000, (%rsp) movl $0x00000000, 4(%rsp) movq %rsp, %rbx movl $0x00000000, 8(%rsp) movl $0x00000000, 12(%rsp) movl $0x00000000, 16(%rsp) [...skipping 4000 lines...] movl $0x00000000, 16376(%rsp) movl $0x00000000, 16380(%rsp) This only happens when T has a non-trivial constructor and the array is initialized using {}. If I do any of the following, g++ generates a simple loop: 1) Remove S::S(); 2) Remove S::S() and initialize S::f in-class; 3) Remove the aggregate initialization (= {}); 4) Compile without -O2. Bugs 59659, 56671 may be relevant. In particular, some of the test cases in bug 59659 seem to still be failing.
Confirmed, I had saw another bug like this before ...
.
I also confirm this. Also present in 5.4.0 and 6.1.0 (at least). The following test case contains 3 scenarios, each one originated from uncommenting the respective line in main(): #include <iostream> using namespace std; struct X { X() { cerr << __func__ << endl; } ~X() { cerr << __func__ << endl; } }; template<typename Type> struct Object1 { Type Value; }; template<typename Type> struct Object2 { Type Value{}; }; int main() { //X object[0x1000]; // (1) //Object1<X[0x1000]> object; // (2) //Object2<X[0x1000]> object; // (3) } Scenarios (1) and (2) produce roughly the same executable, in either -O0 and -Ofast. Scenario (3) takes an enormous time to compile, produces a much larger executable, -Winline complains about not being able to inline things and, on occasion, cc1plus crashes (specially if you raise the size of the arrays involved). Output (for scenario 3): Test.c++: In function 'int main()': Test.c++:14:8: warning: inlining failed in call to 'constexpr Object2<X [4096]>::Object2() noexcept (false)': --param large-function-growth limit reached [-Winline] struct Object2 { Type Value{}; }; ^ Test.c++:19:21: warning: called from here [-Winline] Object2<X[0x1000]> object; // (3)
Dup of bug 92385. *** This bug has been marked as a duplicate of bug 92385 ***