如果 c 代码"through"抛出异常会发生什么?
What happens if exception gets thrown "through" c code?
可能重复:
C++异常会通过C代码安全传播吗?
如果你有c代码,例如png-lib,有你自己的io处理程序,这些处理程序是用c++编写的,并且由于一些io错误而引发异常。让它通过c代码并在c代码之外捕获它可以吗?我知道必须小心内存泄漏,但通常所有结构都是预先分配的。
这是否有效完全取决于编译器。显然,没有一种语言标准可以说明其他语言应该做什么
在最好的情况下,异常将传递C代码并返回到下一个C++级别,同时可能泄漏任何动态分配的C结构。在不太好的情况下,它会崩溃并燃烧!
当然,一种可能性是将C代码编译为C++,同时检查它是否与异常无关。
问题的答案是定义实现。
对于GCC,正如@Kerrek所说,使用-fexceptions
编译C代码将确保在通过C代码引发异常时运行时保持一致。(请注意,现代异常机制不是通过setjmp/longjmp实现的;它们实际上逐帧展开堆栈,以便正确处理析构函数和try/catch块。)
然而,C代码本身可能不会出现异常
acquire a resource
do some stuff
release resource
这里的"获取资源"可以是指malloc
、pthread_mutex_lock
或fopen
。如果您的C++代码是"做一些事情"的一部分,并且它抛出了一个异常,那么。。。哇。
资源泄漏并不是唯一的问题;正确性也是普遍的。想象一下:
subtract $100 from savings account
add $100 to checking account
现在想象一个异常在第一步完成之后,但在第二步完成之前抛出。
简言之,尽管您的实现可能提供了一种让您通过C代码抛出异常的方法,但这是一个坏主意,除非您也编写了知道异常可能抛出的确切位置的C代码。
- 编译时启用了异常
- 异常安全
对于您的C或C++代码来说,如果:
- 在抛出异常和捕获异常之间不需要明确地收集资源
使用C++异常支持编译的代码添加了特殊的钩子,以便在抛出异常且未在该范围内捕获异常时进行清理。在堆栈上分配的C++对象将调用它们的析构函数。
当抛出异常时,C(或不支持异常的C++)中唯一回收的资源是在每个堆栈帧中分配的空间。
GCC手册的这一部分非常有用:
-fexceptions启用异常处理。生成所需的额外代码传播异常。对于某些目标,这意味着GCC将为所有函数生成框架展开信息,这些信息可以产生显著的数据大小开销,尽管这不会影响处决如果未指定此选项,GCC将启用它默认情况下,对于像C++这样通常需要异常的语言处理,并为C等通常不使用的语言禁用它需要。但是,当编译需要与异常正确互操作的C代码用C++编写的处理程序。您也可能希望禁用此选项如果您正在编译不使用异常的旧C++程序处理
异常通常不会真正抛出"through"代码;正如操作所暗示的那样,它们被抛出"over"代码。
例如;至少老派的Objective-C异常通常使用setjmp和longjmp来实现;本质上存储代码的地址以供以后使用。
用类似的机制实现C++异常是有意义的;因此;异常被抛出的代码类型是"through",或者更准确地说是"over",这无关紧要。甚至可以想象这样一种设置,其中Objective-C异常被抛出到C++捕获上,反之亦然。
编辑:作为Bo Persson mentiones;这并不是说C++异常中断C代码不会造成严重破坏和泄漏;但是抛出异常通常是件坏事™全面;所以这不太重要。
PS:真的问了一个问题,同时使用C和C++标记在哪里是相关的,值得称赞。)
C对异常一无所知,因此无法说明会发生什么。
要编写一致的代码,您需要在返回到C库之前捕获异常,转换为错误代码,然后将C库错误转换回另一端的异常。
- 从构造函数抛出异常时如何克服内存泄漏
- 函数如何通知用户它基于函数原型抛出异常?
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- VisualStudios 会抛出异常,而代码块不会 [C++]
- 如果不包含 pthread,为什么 GCC 的线程标准库实现会抛出异常?
- ZMQ::send() 抛出异常并终止 QNX 进程.为什么以及如何从中恢复?
- new(std::nothrow) int[n] 抛出异常
- 为什么g_object_set抛出异常(vcruntime140.dll)?
- 你能防止 std::regex 在无效表达式上抛出异常吗?
- C++子线程抛出异常
- 我们应该在抛出异常之前取消分配内存吗
- std::p riority_queue::p op什么时候会抛出异常
- 在类中抛出异常的最佳方法是什么
- 当在计算constexpr时抛出异常时会发生什么
- 在什么情况下,if语句可以抛出异常
- 有人能确切地解释一下,如果在堆上分配对象数组的过程中抛出异常,会发生什么吗
- 如果构造函数抛出异常会发生什么
- 是什么在这个文件流中抛出异常?
- 如果 c 代码"through"抛出异常会发生什么?
- 这个语法是什么意思?运算符重载和抛出异常