C++:安全使用longjmp和setjmp?

jam*_*o00 39 c++ linux gcc exception longjmp

关于以下内容在linux/gcc上使用C++中的longjmp和setjmp是否安全?

  1. 异常处理(我没有使用longjmp/setjmp实现异常处理.我想知道longjmp/setjmp对标准异常处理会产生什么副作用)
  2. *this 指针
  3. 信号
  4. 智能指针(boost的共享和侵入指针)
  5. 你能想到的任何其他东西.

Mic*_*urr 58

setjmp()/ longjmp()完全颠覆堆栈展开,因此异常处理以及RAII(一般的析构函数).

从标准中的18.7/4"其他运行时支持":

如果任何自动对象将被抛出异常转移控制转移到程序中的另一个(目标)点,那么longjmp(jbuf, val)在将控制转移到同一(目标)点的抛出点的调用具有未定义的行为.

所以底线是setjmp()/ longjmp()在C++中不能很好地发挥作用.

  • 通常,只要有某种方法可以退出C++中的作用域(返回,抛出或其他),编译器就会发出指令来调用dtors来查找由于离开该块而需要销毁的任何自动变量.`longjmp()`只是跳转到代码中的新位置,因此它不会为调用dtors提供任何机会.该标准实际上不那么具体 - 标准并没有说不会被称为dtors - 它说所有的赌注都是关闭的.在这种情况下,您不能依赖任何特定行为. (12认同)
  • 由于智能指针依赖于被破坏,因此您将获得未定义的行为.未定义的行为可能包括不会减少的引用计数.你使用`longjmp()`是'安全的',只要你没有长时间使用可能导致调用dtors的代码.然而,正如David Thornley在评论中指出的那样,setjmp()/ longjmp()即使在直接使用C也是很棘手的 - 在C++中它们是非常危险的.尽可能避免使用它们. (8认同)
  • @jameszhao00:如果你不熟悉智能指针,(现在就熟悉它们)想想其他的东西:`std :: vector`和`std :: string`没有释放它的内存,`std :: fstream`没有关闭它的文件和类似的东西. (3认同)

Mar*_*rkR 6

它不是特定于Linux或gcc; 如果你使用longjmp来保留带有析构函数的自动变量的上下文,setjmp/longjmp和C++不能很好地协同工作.

析构函数不会运行,这可能导致内存泄漏或其他不良行为.