使用MSVS 2010构建问题和C++标准。

9
我正在尝试使用msvs 2010构建以下git中找到的项目:https://github.com/Joonhwan/exprtk。问题是,当我在exprtk.hpp文件中注释掉第48行的“#define exprtk_lean_and_mean”时,我会得到以下编译器错误:
Error   1   error C1128: number of sections exceeded object file format limit : compile with /bigobj

通过谷歌搜索,似乎表明编译翻译单元已编译成比任意限制更大的东西,并在命令行中添加“bigobj”应该解决问题(它确实这样做)。使用gcc(4.3)编译代码没有任何问题。
我的问题是:
1. c++是否对可以在翻译单元中使用的类型数量设置了限制?
2. 这个项目中代码的布局方式是否是不好的实践?(当我谷歌搜索时,注意到很多boost库都有同样的问题,例如:Boost.Sprit)
2个回答

15
C++对一个翻译单元中所能包含的类型数量是否有限制?
请注意,这些参数的最大值留给特定实现开放。标准仅强制实现必须支持的最低要求。实现将记录它支持的最大值,在这种情况下,MSVC实现做到了这一点。
这些定义在C++标准的一个特殊部分中。
《附录B - 实现数量》
因为计算机是有限的,C++实现在它们可以成功处理的程序大小方面不可避免地受到限制。每个实现都应记录已知的那些限制。此文档可能引用固定的限制(如果存在),说明如何将变量限制计算为可用资源的函数,或说明固定限制不存在或不为人知。
这些限制可能限制包括下面所描述的数量或其他数量。建议使用方括号后面的数字作为该数量的最小值。然而,这些数量只是指导方针,不确定符合性。
- 复合语句、迭代控制结构和选择控制结构的嵌套级别[256]。 - 条件包含的嵌套级别[256]。 - 在声明中修改算术、结构、联合或不完整类型的指针、数组和函数声明符(任意组合)的嵌套级别[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 语句中的 case 标签(不包括任何嵌套 switch 语句的标签) [16 384]。
单个类、结构体或联合体中的数据成员 [16 384]。
单个枚举中的枚举常量 [4 096]。
单个 struct-declaration-list 中嵌套的类、结构体或联合体定义级别 [256]。
由 atexit() 注册的函数数量 [32]。
直接和间接基类 [16 384]。
单个类的直接基类 [1 024]。
单个类中声明的成员 [4 096]。
一个类中最终重载的虚函数,可访问或不可访问 [16 384]。
一个类的直接和间接虚基类 [1 024]。
类的静态成员 [1 024]。
类中的友元声明 [4 096]。
类中的访问控制声明 [4 096]。
构造函数定义中的成员初始化器 [6 144]。
一个标识符的作用域限定 [256]。
嵌套的外部声明 [1 024]。
模板声明中的模板参数 [1 024]。
递归嵌套的模板实例化 [17]。
每个 try 块中的处理程序数量 [256]。
单个函数声明中的 throw 规范 [256]。


这些方括号中的最小值,因为它们是“推荐”的,不能被用作定义编译器是否符合标准的最小值 - 这正确吗? - Gelly Ristor
@GellyRistor:是的,这是真的。但大多数主流符合标准的编译器至少支持这些最低要求,并且他们确实做到了。 - Alok Save
3
还有一个问题,根据上面的列表,哪一个定义了msvc 2010编译器抱怨的“部分”的推荐数量? - Gelly Ristor
@GellyRistor:我认为可能是二进制对象大小的问题,所以我将其加粗了,但也可能是作用域中标识符数量等其他值。我不确定,因此发布了整个列表。 - Alok Save
我理解了,现在有意义了。所以看起来是编译器出了问题,而不是库出了问题。 - Gelly Ristor
1
@GellyRistor:可能是“一个翻译单元中的外部标识符”,再加上MSVS的“编辑和继续”选项。该选项将每个函数放在自己的部分中,以便于轻松替换。 - MSalters

7
限制在于旧版本的MSVC和相应的链接器中使用的OBJ格式。因此,尽管这个限制是任意的,但它不能成为新版本编译器的默认行为。请查看/bigobj选项的描述:

在Visual C++ 2005之前发布的链接器无法读取使用/bigobj生成的.obj文件。


1
而且由于您使用的是 C++(而不是 C),混合来自几个不同 Visual Studio 版本的编译代码可能是行不通的。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接