为何返回newMesh时函数提前返回,返回nullptr时却正常?
我在使用ufbx库解析.fbx文件时遇到了诡异的流程问题:
- 返回
nullptr时,代码能正常执行到ufbx_free_scene,断点可以命中,循环也能正常跑完。 - 但返回预先定义的
std::shared_ptr对象newMesh时,程序会直接跳过后续循环和ufbx_free_scene调用提前返回。查看反汇编发现,创建newMesh后就出现了提前返回的逻辑。 - 已经通过SCons调用MSVC编译,且添加了
/Od参数关闭优化,仍无法解决该问题。
可能的原因及排查方向
1. shared_ptr构造/赋值触发未捕获异常
如果newMesh的构造、拷贝/移动操作,或者其管理的Mesh对象初始化过程中抛出了未捕获的异常,程序会直接进入异常处理流程,跳过后续所有清理代码。
- 开启MSVC的「第一次机会异常」捕获(调试窗口→异常设置,勾选所有C++异常),检查是否有异常被抛出但未被处理。
- 检查Mesh类的构造函数、拷贝/移动运算符,以及
shared_ptr绑定资源的代码是否存在潜在异常点。
2. 代码中存在隐式提前返回逻辑
仔细核对创建newMesh到return newMesh之间的代码,是否有隐藏的分支触发了提前返回:
- 比如某个函数调用内部包含
return语句,或者未注意到的条件判断:if (init_failed) { return newMesh; // 此处提前返回,跳过后续循环和清理 } - 排查是否存在
goto语句跳转到return代码块的情况。
3. SCons编译配置未实际生效
即使添加了/Od,也可能因SCons配置逻辑问题,导致编译选项被覆盖:
- 直接查看编译时的完整命令行,确认
/Od确实存在,没有被/O2、/Ox等优化参数覆盖。 - 手动使用MSVC的
cl.exe直接编译对应源文件,明确传入/Od,验证问题是否依然存在,排除SCons配置的影响。
4. 调试器显示误导
部分情况下,调试器的断点或反汇编行号映射可能出现错误,导致看起来代码被跳过,但实际已经执行:
- 在循环内部、
ufbx_free_scene调用前添加日志输出(比如printf或OutputDebugString),通过日志确认代码是否真的未执行,而非仅依赖调试断点。
5. shared_ptr返回值优化的特殊情况
虽然关闭了优化,但MSVC某些版本对返回值优化(RVO)的处理可能存在特殊逻辑。尝试将newMesh的构造与return操作分开:
// 先构造完成 std::shared_ptr<Mesh> newMesh = ...; // 执行完所有循环和清理 for (...) { ... } ufbx_free_scene(scene); // 最后返回 return newMesh;
避免在return语句中直接构造shared_ptr,看是否能解决问题。
内容的提问来源于stack exchange,提问作者CakePlusPlus
相关产品推荐
相关产品推荐

