为什么当 LuaJIT 抛出异常时 std::uncaught_exception 函数返回 false?
2016-7-21 2:34:51
收藏:0
阅读:78
评论:1
LuaJIT 手册 说明:
用 catch(...) 可以在 C++ 代码中捕获 Lua 异常。可以从 Lua 堆栈中获取相应的 Lua 异常信息。
这个功能可以正常运行,但是 std::uncaught_exception() 函数却不返回 true。
下面是一个最小示例,以说明此问题。checker 的析构函数应在堆栈展开期间执行,因此其中的 std::uncaught_exception() 应该返回 true,但它没有。
这是为什么?我是否误解了流程,或者 LuaJIT 进行了一些问题的异常抛出?
struct checker {
~checker() {
if(std::uncaught_exception()) {
// 此条件应评估为 true,但实际上不是
}
}
}
auto l = luaL_newstate();
try {
{
checker c;
luaL_checknumber(l, -1); // 这行代码会引发 LuaJIT 异常
}
}
catch(...) {
// 这将被执行,按预期工作
auto err = lua_tostring(state, -1); // 读取 LuaJIT 错误,此功能也正常
// ...
}
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
std::uncaught_exception是 C++ 异常处理机制的一个函数。而 LuaJIT 所做的正好相反,它并没有触发throw,而是利用了隐藏的系统调用来模拟异常处理机制的行为。但就像任何表面一样,它只是一个模仿,不是真正的东西。想象一下,C++ 代码 "throw X();" 被转换为以下代码:
auto thrown = x(); auto handler = find_handle_for_exception(thrown); if(!handler) std::terminate(); auto except = allocate_exception(thrown); handling_exception = true; unwind_stack_to_handler(handler); handling_exception = false; handler(except); //将控制转移到句柄。而 LuaJIT 则了解所有这些隐藏的内部系统调用。因此,当它想要 "throw" 异常时,它采取了以下步骤:
auto handler = find_handle_for_exception(); //只有匹配 ... if(!handler) std::terminate(); unwind_stack_to_handler(handler); handler(); //将控制转移到句柄。在这个伪代码中,
uncaught_exception通过读取handling_exception的值来工作。但是糟糕的是,LuaJIT 没有在它的版本中更新那个变量。可能是因为它是 C++11 的新功能,他们从未在各种系统上检查过它的工作方式。或者可能在某些系统上确实有效,但在 MacOSX 上无效。这总是一种危险,当您尝试在您的抽象提供的某些功能上进行仿真时,它可能无法以完全互操作的方式完成。我不知道为什么 LuaJIT 不能像正常人一样抛出真正的 C++ 异常...