C++11: g++-4.7 internal compiler error

2019-04-06 04:48发布

The following code:

#include <iostream>
#include <array>
using namespace std;

constexpr int N = 1000000;
constexpr int f(int x) { return x*2; }

typedef array<int, N> A;

template<int... i> struct F { static constexpr A f() { return A{{ ::f(i)... }}; } };

template<class A, class B> struct C {};
template<int... i, int... j> struct C<F<i...>, F<j...>> : F<i..., (sizeof...(i)+j)...>
{
        using T = F<i..., (sizeof...(i)+j)...>;
};

template<int n> struct S : C<typename S<n/2>::T, typename S<n-n/2>::T> {};
template<> struct S<1> : F<0> { using T = F<0>; };

constexpr auto X = S<N>::f();

int main()
{
        cout << X[3] << endl;
}

Produces an internal compiler error in GCC 4.7 in -std=gnu++11 mode.

$ g++ -std=gnu++11 test.cpp
g++-4.7.real: internal compiler error: Killed (program cc1plus)

What is going wrong?

2条回答
欢心
2楼-- · 2019-04-06 05:24

It seems that your program requires an unreasonable amount of memory (perhaps because of too many template expansions).

Using a recent g++-trunk :

gcc version 4.8.0 20121026 (experimental) [trunk revision 192860] (GCC) 

with the following zsh limits:

   % limit          
   cputime         unlimited
   filesize        unlimited
   datasize        15000MB
   stacksize       8MB
   coredumpsize    400MB
   memoryuse       15000MB
   maxproc         128166
   descriptors     1024
   memorylocked    64kB
   addressspace    16000MB
   maxfilelocks    unlimited
   sigpending      128166
   msgqueue        819200
   nice            0
   rt_priority     0
   rt_time         unlimited

(this on Debian/Sid/AMD64 with i3770K intel processor & 16Gb RAM)

I am getting:

  % time g++-trunk -std=gnu++11 andrew.cc -o andrew
  virtual memory exhausted: Cannot allocate memory
  g++-trunk -std=gnu++11 andrew.cc -o andrew :
  108.25s user 3.28s system 89% cpu 2:03.98 total

So it seems that template expansion requires so much memory that you program is not reasonable.

I am not sure that would be accepted as a GCC bug. C++ tenplate macroexpansion is known to be Turing complete, and you just hit the wall. And the GCC trunk does report a fatal, but understandable, error.

The moral of the story might be to setrlimit(2) appropriately (with limits compatible with your system and hardware), perhaps using limit zsh builtin or ulimit bash builtin.

查看更多
对你真心纯属浪费
3楼-- · 2019-04-06 05:47

An internal error means that you hit a compiler bug.

查看更多
登录 后发表回答