【发布时间】:2017-06-23 07:49:25
【问题描述】:
假设我有一个用 c++ 实现但公开了纯 c 接口的共享库。然后在 c 程序中使用该库。
如果异常从 c++ 库逃逸到 c 应用程序中,gcc 是否对会发生什么做出任何保证?
会不会,例如总是终止程序?
我主要对 x64 和 ARMv7-R 上的 Linux 上的 gcc 的答案感兴趣,但也欢迎有关其他操作系统、编译器和体系结构的答案。
编辑:
明确一点:我不是在谈论让异常通过 c 函数,然后在调用 c++ 函数或与 c 或 c++ 回调交互时被捕获。应用程序代码本身是纯 c。在某些时候,它会调用共享库(内部是纯 c++)的一个函数,并且在该函数返回之前不会调用任何应用程序代码。还假设我无法控制用于编译应用程序代码的标志。
【问题讨论】:
-
我相信这样的异常将被视为未捕获的异常(即生成对
std::terminate的调用),除非C代码使用-fexceptions编译,在在这种情况下异常可以传播(尽管最终可能仍然未被捕获)。但是,我没有可验证的来源。 -
这就是为什么,如果混合 C 和 C++,一个共同的准则是
main()被编译为 C++,而不是 C 并且extern "C"函数捕获异常并且不让它们传播给调用者。要么,要么 C++ 代码在没有异常支持的情况下编译,或者根本不抛出。通过 C 函数传播 C++ 异常是未定义的。 -
@Peter:是的,我对这种情况不满意,但事实就是这样。该库由 c 程序使用-我无法更改。如果我忘记在边界程序终止处捕获一些异常 - 通常 - 我可以接受(特别是,我通常不会尝试从
bad_alloc中恢复),但我不想冒未定义行为的风险。所以我面临的问题是我是否应该将所有接口函数的实现包装到一个额外的try { ...} catch(...){ std::terminate(); }块中以确保安全,或者我是否可以依赖编译器来产生相同的效果。 -
@Peter:由于 gcc afaik 定义了一些在 c++ 标准中未定义的东西,以便与 C 保持兼容,我希望这是其中之一。
-
@Peter:你有 "C++ 异常通过 C 函数的传播是未定义的" 的源代码(显然不能在c++标准)?如果是这样,我很乐意接受这个对我的问题的回答。