在静态库之外抛出C ++异常?

时间:2012-12-21 13:14:31

标签: c++ exception static-libraries

通常,异常不得传播模块边界,例如Herb Sutters C ++编码标准(第62项)中所述。当使用不同的编译器或仅编译器设置进行编译时,这可能会崩溃。

我可以理解这个问题,例如动态链接库。但我想知道它是否适用于静态库。静态库是上述规则意义上的模块吗?如果使用其他编译器设置编译库(例如对齐),如果从静态库中抛出异常并在应用程序中捕获异常,程序可能会崩溃吗?

3 个答案:

答案 0 :(得分:11)

通常,静态库必须由相同的编译器和相同的编译器设置(大多数)编译,以与可交付物(动态库或可执行文件)兼容。

然后,您可以在静态库的边界之外抛出异常,因为它与编译器生成的一组.obj文件没有太大区别。你很明显可以在不同的.obj模块之间抛出异常。

编辑:

总结评论:

  1. 如果您使用的是用于编译库的相同编译器和编译器设置,则只能使用静态库。
  2. 您可以在使用相同编译器和编译器设置编译的模块之间抛出异常。
  3. 从1)和2)接着你可以从静态库中抛出异常,因为如果你正在使用它,那意味着你正在使用相同的编译器和编译器设置,因此你可以抛出异常。

答案 1 :(得分:5)

Herb Sutters的描述也适用于静态库:

  

C ++异常处理没有普遍存在的二进制标准。   不允许异常在两段代码之间传播,除非   您可以控制用于构建两者的编译器和编译器选项   两侧;否则,模块可能不支持兼容   异常传播的实现。通常,这归结为   to:不要让异常跨模块/子系统边界传播。

答案 2 :(得分:1)

这取决于Herb在“模块”中的含义。问题没有 只涉及例外;他们可以使用C ++来关注任何事情 接口

异常交叉翻译时肯定没有问题 单位边界的来源编制为同一部分 零件。在组件之间,如果它们都是相同的组成部分 应用程序,并确保它们都使用 相同的编译器,使用相同的编译器选项,它可能是安全的, 虽然在动态之间交叉时可能会出现问题 库,取决于库的加载方式。 (在 一般来说,这只是Unix系统上的一个问题所在 动态加载组件中符号的可见性 由传递给动态加载程序的选项控制。)作为 一般规则:安排编译所有应用程序 使用相同的编译器和相同的编译器选项,和你一样 在应用程序中应该没有真正的问题(尽管如此 您可能必须确保所有动态组件都是 显式加载,至少在Unix下)。之间 “应用程序”,您正在加载或加载 “外国”软件,Herb的限制还远远不够。在 练习,您在应用程序之间交叉的界面 必须在C中定义。可能仍有限制, 取决于代码的加载方式和其他动态代码 正在使用已加载的组件。

静态链接将消除有关方法的问题 库已加载,但不会改变任何其他内容。