通常,异常不得传播模块边界,例如Herb Sutters C ++编码标准(第62项)中所述。当使用不同的编译器或仅编译器设置进行编译时,这可能会崩溃。
我可以理解这个问题,例如动态链接库。但我想知道它是否适用于静态库。静态库是上述规则意义上的模块吗?如果使用其他编译器设置编译库(例如对齐),如果从静态库中抛出异常并在应用程序中捕获异常,程序可能会崩溃吗?
答案 0 :(得分:11)
通常,静态库必须由相同的编译器和相同的编译器设置(大多数)编译,以与可交付物(动态库或可执行文件)兼容。
然后,您可以在静态库的边界之外抛出异常,因为它与编译器生成的一组.obj文件没有太大区别。你很明显可以在不同的.obj模块之间抛出异常。
编辑:
总结评论:
答案 1 :(得分:5)
Herb Sutters的描述也适用于静态库:
C ++异常处理没有普遍存在的二进制标准。 不允许异常在两段代码之间传播,除非 您可以控制用于构建两者的编译器和编译器选项 两侧;否则,模块可能不支持兼容 异常传播的实现。通常,这归结为 to:不要让异常跨模块/子系统边界传播。
答案 2 :(得分:1)
这取决于Herb在“模块”中的含义。问题没有 只涉及例外;他们可以使用C ++来关注任何事情 接口
异常交叉翻译时肯定没有问题 单位边界的来源编制为同一部分 零件。在组件之间,如果它们都是相同的组成部分 应用程序,并确保它们都使用 相同的编译器,使用相同的编译器选项,它可能是安全的, 虽然在动态之间交叉时可能会出现问题 库,取决于库的加载方式。 (在 一般来说,这只是Unix系统上的一个问题所在 动态加载组件中符号的可见性 由传递给动态加载程序的选项控制。)作为 一般规则:安排编译所有应用程序 使用相同的编译器和相同的编译器选项,和你一样 在应用程序中应该没有真正的问题(尽管如此 您可能必须确保所有动态组件都是 显式加载,至少在Unix下)。之间 “应用程序”,您正在加载或加载 “外国”软件,Herb的限制还远远不够。在 练习,您在应用程序之间交叉的界面 必须在C中定义。可能仍有限制, 取决于代码的加载方式和其他动态代码 正在使用已加载的组件。
静态链接将消除有关方法的问题 库已加载,但不会改变任何其他内容。