我有三个免费功能:F0、F1和F2。 F0 调用 F1,F1 又调用 F2。
F0 和 F2 是 C++ 函数,而 F1 是 C 函数。 F2 通过以下方式暴露给 F1:extern "C"
各个免费函数的代码如下:
~~~~ F0.cpp ~~~~
void f0()
{
try
{
f1();
}
catch (...)
{}
}
~~~~ F0.cpp ~~~~
~~~~ F1.c ~~~~
void f1()
{
f2();
}
~~~~ F1.c ~~~~
~~~~ F2.cpp ~~~~
void f2()
{
throw 1
}
~~~~ F2.cpp ~~~~
问题:
f2progress中通过f1抛出的异常是否在f0中被正确捕获?
或者是由于未处理异常而调用 std::unexpected ,或者整个事情应该是未定义的行为? - 如果是这样,标准中的哪里讨论了这个特定上下文中的异常处理。
请注意,这不是关于处理 C 中的异常,而是关于异常可以流过 C 层(如果有的话)并在调用 C++ 层中捕获的情况下会发生什么 - 以及任何由此产生的副作用等。
这是特定于平台和特定于编译器的问题。
例如,在Linux/GCC上,您必须使用
-fexceptions
选项编译C代码,然后将构建展开表并且异常将抛出C代码。
来自 https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/Code-Gen-Options.html#index-fexceptions
-fexceptions
启用异常处理。生成传播所需的额外代码 例外情况。对于某些目标,这意味着 GCC 生成帧展开 所有函数的信息,这可能会产生大量数据 开销,尽管它不影响执行。如果您不指定 这个选项,GCC 默认为 C++ 等语言启用它 通常需要异常处理,并针对语言禁用它 像 C 一样,通常不需要它。但是,您可能需要 编译需要互操作的C代码时启用此选项 正确地使用用 C++ 编写的异常处理程序。您可能还希望 如果您正在编译不支持的旧版 C++ 程序,请禁用此选项 使用异常处理。
我对 Visual C++/Windows 开发不太熟悉,但我相信如果您使用 /EHa 选项编译 C++ 和 C 代码(允许混合结构化和 C++ 异常),异常处理将使用通用机制
当我意识到我的 MSVC 项目正在使用一个 C 库时,我偶然发现了这个问题,该库传递了一个引发异常的 C++ 错误处理程序。发布版本会在到达 catch 子句之前崩溃,并出现意外的“写访问冲突”。
在 Visual Studio 中,转到项目的属性页面 > 配置属性 > C/C++ > 代码生成 > 启用 C++ 异常。将属性设置为“是,使用外部 C 函数 (/EHs)”,让编译器知道它还应该预期外部“C”函数会抛出异常。