如果您有c代码,例如png lib,您自己的io处理程序是用c ++编写的,并且由于某些io错误而引发异常。让它通过c代码并在c代码之外捕获它是否可以?我知道必须注意内存泄漏,但通常所有结构都要预先分配。
答案 0 :(得分:9)
完全取决于编译器是否可行。没有任何一种语言标准可以明确说明其他语言应该做什么。
在最好的情况下,异常将传递C代码并返回到下一个C ++级别,同时可能泄漏任何动态分配的C结构。在不太好的情况下,它会崩溃并燃烧!
当然,有可能将C代码编译为C ++,同时还要检查它是否为异常中性。
答案 1 :(得分:6)
您的问题的答案是实施定义。
对于GCC,正如@Kerrek所说,用-fexceptions
编译C代码将确保在通过C代码抛出异常时运行时保持一致。 (请注意,现代异常机制 not 只是通过setjmp / longjmp实现;它们实际上逐帧展开堆栈,以便正确处理析构函数和try / catch块。)
但是,C代码本身可能不会期望通过它抛出异常。很多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代码,知道可能引发异常的确切位置。
答案 2 :(得分:5)
如果它是:
,你的C ++代码是可以的如果符合以下条件,您的C或C ++代码就可以了:
使用C ++异常支持编译的代码添加了特殊的挂钩,以便在抛出异常时清除并且不会在该范围中捕获。在堆栈上分配的C ++对象将调用其析构函数。
抛出异常时,在C(或C ++中无异常支持)中回收的唯一资源是在每个堆栈帧中分配的空间。
GCC手册的This section非常有帮助:
-fexceptions Enable exception handling. Generates extra code needed to propagate exceptions. For some targets, this implies GCC will generate frame unwind information for all functions, which can produce significant data size overhead, although it does not affect execution. If you do not specify this option, GCC will enable it by default for languages like C++ which normally require exception handling, and disable it for languages like C that do not normally require it. However, you may need to enable this option when compiling C code that needs to interoperate properly with exception handlers written in C++. You may also wish to disable this option if you are compiling older C++ programs that don't use exception handling.
答案 3 :(得分:4)
异常通常不会被“通过”代码抛出;正如行动所暗示的那样,它们被“抛弃”代码。
作为一个例子;至少老派的Objective-C异常通常用setjmp和longjmp实现;基本上存储代码的地址供以后使用。
使用类似的机制实现C ++异常是有意义的;就这样;异常被抛出的代码类型,或者更准确地说,“over”很少,如果有的话。人们甚至可以想象一个设置,其中一个Objective-C异常被抛出C ++ catch,反之亦然。
编辑:正如博佩森提到的那样;这并不是说中断C代码的C ++异常不会造成破坏和泄漏;但被抛出的异常通常都是Bad Thing™;所以它不太重要。
PS:实际上问一个问题,即使用C和C ++标签是否相关。 ;)
答案 4 :(得分:1)
C对异常一无所知,所以不可能说出会发生什么。
要编写符合规范的代码,您需要在返回C库之前捕获异常,转换为错误代码,然后将C库错误转换回另一端的异常。