有没有安全的方法在 C++ 中使用 setjmp() 和 longjmp() ?
我的印象是,在 C++ 中使用 setjmp()
和 longjmp()
几乎肯定会弄乱堆栈,因为这些函数不会像这样执行展开操作,例外情况。但是,此 MSDN 页面表明可以告诉 Microsoft 实现调用本地对象的析构函数,这意味着谨慎使用这些函数可能是安全的。
在 C++ 中使用 setjmp()
和 longjmp()
时,是否有一种可移植的方法来确保程序的正确性? C++ 中的最佳实践表明,异常最好不要用于流程控制,但在需要高度不寻常的流程(例如协程和闭包)的情况下,是否总是最好使用异常来代替这些函数?
I was under the impression that using setjmp()
and longjmp()
in C++ was almost guaranteed to mess up the stack, since these functions don't perform unwinding like, say, exceptions do. This MSDN page, however, indicates that the Microsoft implementation can be told to invoke the destructors of local objects, which implies that careful use of these functions could be safe.
Is there a portable means of ensuring program correctness when using setjmp()
and longjmp()
in C++? Best practices in C++ indicate that exceptions are best not used for flow control, but in a situation that requires highly unusual flow (e.g., coroutines and closures), is it always preferable to use exceptions in lieu of these functions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您有一些非常奇怪的要求,不允许您使用条件/循环/中断正常控制程序流程,我更愿意使用异常而不是 jmp。
在某些情况下,使用异常来控制流程是可以接受的。我认为 Boost.Graph 的搜索函数之一会抛出异常,以便从深度递归快速返回调用者。
If you have some really weird requirement that doesn't allow you to control the flow of the program normally, with conditionals/loops/breaks, I would prefer to use an exception over jmp.
There are scenarios where using an exception to control flow is acceptable. I think one of Boost.Graph's search functions throws an exception to quickly return to the caller from deep recursion.
我以前用过它们,但只在一种情况下使用过:我正在用 C 语言为操作系统类创建操作系统内核;它们用于异常处理。
我的理解是,它们用于处理低级代码(例如操作系统)时的异常处理。对于一般的 C++ 软件,我只使用
try
catch
。I've used them before, but only under one circumstance: I was creating an OS kernel in C for an OS class; they were used for exception handling.
My understanding is that they're used for exception handling when dealing with low-level code, like an operating system. For general C++ software, I'd just use
try
catch
.