我正在尝试编译一个大约5.7 MB的C ++文件。我正在64位Linux系统上构建一个64位Linux可执行文件。遗憾的是,g ++ 4.7.2不合作:
g++: internal compiler error: Killed (program cc1plus)
使用top
进行观察表明该进程在此之前达到了大约2.2 GB的内存。我尝试设置--param gcc-min-expand=0
并使用--param gcc-min-heapsize
,但这并没有解决问题。使用-O0
禁用优化也无济于事。
我也尝试用clang编译,但结果相似。它在超过2演出的记忆之后也被分割。我没有尝试任何额外的选项,因为我不太熟悉它。
有问题的源文件包含几个地图的C ++ 11样式初始化。
typedef std::map<std::string, int> StringToIntMap;
StringToIntMap someData = {{"SOMESTRING", 1}, ..};
我最想要的是用gcc编译文件,虽然如果clang可以工作,我也可以忍受它。从知道内部人员的人那里了解幕后发生的事情也是有帮助的。如果我有一个300 000个元素的映射,其中字符串大约5个字节长,并且int
对应于每个,那就是几兆字节的数据,我无法想象初始化器如何将它吹到需要千兆字节才能编译。
并抢占评论,我不应该有这么大的源文件。我知道我可以在运行时从数据文件中读取数据,这就是程序现在所做的,但我的用例是程序的执行时间是最重要的因素。
答案 0 :(得分:4)
允许编译器对许多语言结构中支持的级别/数量的数量设置实现定义的限制。
附录B列出了符合的编译器所需的最小数量。
从附录B中,粗略显示最相关的:
限制可能会限制包含以下所述数量的数量 其他。建议将每个数量后面的括号内的数字作为 该数量的最小值。但是,这些数量只是指导方针 不确定合规性。
- 嵌套复合语句,迭代控制结构和选择控制结构的级别 [256]。
- 嵌套条件包含级别[256]。
- 指针,数组和函数声明符(以任意组合)修改类,算术或incom- 在声明[256]中填写类型。
- 在完整表达式[256]中嵌套带括号的表达式的级别。
- 内部标识符或宏名称中的字符数[1 024]。
- 外部标识符中的字符数[1 024]。
- 一个翻译单元中的外部标识符[65 536]。
- 具有块范围的标识符在一个块[1 024]中声明。
- 在一个翻译单元中同时定义宏标识符[65 536]。
- 一个函数定义[256]中的参数。
- 一个函数调用[256]中的参数。
- 一个宏定义[256]中的参数。
- 一次宏调用中的参数[256]。
- 一个逻辑源行中的字符[65 536]。
- 字符串文字中的字符(连接后)[65 536]。
- 物体的大小[262 144]。
- #include文件的嵌套级别[256]。
- switch语句的大小写标签(不包括任何嵌套switch语句的大小写)[16 384]。
- 单个班级的数据成员[16 384]。
- 单个枚举中的枚举常量[4 096]。
- 单个成员规范[256]
中嵌套类定义的级别- atexit()[32]注册的功能。
- at_quick_exit()[32]注册的功能。
- 直接和间接基类[16 384]。
- 单个班级的直接基类[1 024]。
- 成员在一个班级[4 096]中宣布。
- 最终覆盖类中的虚函数,可访问与否[16 384]。
- 类[1 024]的直接和间接虚拟基础。
- 类[1 024]的静态成员。
- 课堂上的朋友声明[4 096]。
- 类[4 096]中的访问控制声明。
- 构造函数定义中的成员初始值设定项[6 144]。
- 一个标识符的范围限定[256]。
- 嵌套外部规范[1 024]。
- 递归constexpr函数调用[512]。
- 模板声明中的模板参数[1 024]。
- 递归嵌套模板实例化,包括模板参数推导期间的替换(14.8.2)[1 024]。
- 每个试块的处理程序[256]。
- 在单个函数声明[256]上抛出规范。
- 占位符数量(20.8.9.1.4)[10]
现在,初始化列表实际上只是从许多参数中“构造”而且显然GCC并不完全支持您提供的数量/体积。
手册页中可能有一些选项可以减轻这种情况:
-mlarge-data
(这是默认设置)-mlarge-text
(也是默认值)