C++ C++;11:g++-4.7内部编译器错误
以下代码:C++ C++;11:g++-4.7内部编译器错误,c++,linux,gcc,c++11,g++,C++,Linux,Gcc,C++11,G++,以下代码: #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{{ ::
#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;
}
出了什么问题?内部错误意味着您遇到了编译器错误。您的程序似乎需要不合理的内存量(可能是因为太多的模板扩展) 使用最近的
g++-trunk
:
gcc version 4.8.0 20121026 (experimental) [trunk revision 192860] (GCC)
具有以下zsh限制:
% 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
(这是在带有i3770K intel处理器和16Gb RAM的Debian/Sid/AMD64上实现的)
我得到:
% 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
所以,模板扩展似乎需要太多内存,所以您的程序是不合理的
我不确定这是否会被接受为GCC错误。C++模板的宏扩展是图灵完成,你刚碰到了墙。GCC主干确实报告了一个致命但可以理解的错误
这个故事的寓意可能是适当地(限制与您的系统和硬件兼容),可能使用
limit
zsh内置或ulimit
bash内置。在4.7.1上,我有cc1plus:在总共401997824字节之后,内存不足分配1048576字节。看起来像是一个编译器错误。我在4.7.2上,有32GB的内存。这两者中的任何一个都可以解释差异。可能是因为这里有8GB,但是当减小N
的值时,它就会正确编译。@Andrew Tomazos:是的;请花点时间报告一下这个bug,我想知道~10^6次扩展到底会消耗32GB的内存。递归深度很小,否则将达到512深度限制。它适用于N=10000,因此看起来它似乎在以某种方式使用O(N^2)空间,但它应该只使用O(NlogN)空间。原因很简单:编译器希望(对大多数用户来说应该)在其内部表示中保留大量数据。因此,实际的扩展发生在内部表示(Gcc-Generic)上,它比您想象的更复杂(例如,因为它记住每件事情的源位置)。记住源位置不足以解释资源需求的渐进增长。对于像这个一样大的持续爆炸,GCC每次实例化大约需要32kb,这是荒谬的。然后请通过提交相关补丁来贡献给GCC。clang++编译了这个(在增加-fconstexpr步骤后),在大约1.5G内存中,在10秒内没有问题。g++生长到15G,约4分钟后死亡。(是的,经过这么多年,它仍然这样做)。
% 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