1

我有以下用 C++ 编写的 lua_CFunction:

int my_function(lua_State* L) {
    int x = 0;
    try {
        x = do_cpp_stuff_that_invokes_lua_API_as_well();
    } catch(const std::exception& ex) {
        lua_pushstring(ex.what().c_str());
        lua_error(L);
    }
    return x;
}

我的问题如下:是否可以执行 lua_error(L) 或调用任何可能 longjmp 的 lua 函数:

  • 在尝试块中?
  • 在 catch 块中?

我只通过不分配任何依赖于析构函数(字符串等)的东西来处理分配在堆栈上的变量。如果我需要这样做,那么该范围内的所有 lua 函数都包含在一个 pcall 中,如果该 pcall 失败,则会向我发布的这个函数抛出一个异常。只是我关心的是 try-catch 块。

非常感谢

4

2 回答 2

3

相关规则是(§18.10 [support.runtime]/p4):

函数签名longjmp(jmp_buf jbuf, int val)在本国际标准中具有更多限制行为。如果将 and 替换为and ,setjmp/longjmp 则调用对具有未定义的行为,并且将为任何自动对象调用任何非平凡的析构函数。setjmplongjmpcatchthrow

C++ 标准没有以其他方式限制setjmpand的使用longjmp

于 2014-09-08T12:23:47.397 回答
1

如果你从一个 catch 块做一个长跳转,你至少会泄漏用于存储异常对象的内存。编译器生成代码以释放从 catch 块作用域引出的控制流路径上的内存。如果您跳远,则不会采用这些路径。

Sun Studio 的文档明确禁止混合异常和 longjmp:

特别是,您不能 longjmp 进入或退出 try-block 或 catch-block(直接或间接),或 longjmp 超过自动变量或临时变量的初始化或非平凡破坏。

于 2015-04-13T15:50:34.130 回答