C++异常会通过C代码安全传播吗?

sha*_*oth 31 c c++ exception-handling exception visual-c++

我有一个C++应用程序调用SQLite(SQLite在C中)sqlite3_exec(),它反过来可以调用我在C++中实现的回调函数.SQLite被编译成静态库.

如果异常转义我的回调,它会通过SQLite的C代码安全地传播到调用sqlite3_exec()的C++代码吗?

小智 29

我猜这是依赖于编译器的.但是,在回调中抛出异常将是一个非常糟糕的主意.它要么完全不起作用,要么SQLite库中的C代码将无法处理它.考虑这是否是SQLite中的一些代码:

{
  char * p = malloc( 1000 );
  ...
  call_the_callback();  // might throw an exception
  ...
  free( p );
}
Run Code Online (Sandbox Code Playgroud)

如果异常"有效",则C代码无法捕获它,并且永远不会释放p.当然,库可能已分配的任何其他资源也是如此.

  • 出于同样的原因,我甚至不会从C++库调用的回调代码中抛出异常,除非它的文档明确允许这种行为.有很多(坏)代码写在没有例外的情况下. (7认同)

Han*_*ant 14

已经存在用于中止API调用的回调协议.来自文档:

如果sqlite3_exec()回调返回非零,则sqlite3_exec()例程将返回SQLITE_ABORT,而不会再次调用回调而不运行任何后续SQL语句.

我强烈建议你使用它而不是例​​外.


Ant*_*ert 10

SQLite期望您在出错时返回SQLITE_ABORT,并返回0返回代码,没有错误.所以你应该把你所有的C++回调包装在try catch中.然后在catch中返回一个SQLite SQLITE_ABORT错误代码,否则为零.

如果你绕过通过SQLite返回会出现问题,因为它不会释放/完成从你的回调返回后它执行的任何代码.这将导致无法解决的问题,其中一些问题可能非常模糊.