我的程序有这个功能:
vector<itemPtr> Level::getItemsAt(const Point& pt)
{
vector<itemPtr> vect(items.size());
// copy all items at pt's position to vect
remove_copy_if(items.begin(), items.end(), vect.begin(),
boost::bind(matchesPosition<itemPtr>, _1, pt));
// update LevelMap and return
map.setHasItem(pt, false);
return vect;
}
这编译得很好(我使用g ++,我的gcc版本是4:4.4.1-1ubuntu2),但是当我运行程序时它会跳过return语句。
我介绍了gdb,在前一行设置了断点,并得到了这个:
Breakpoint 1, yarl::level::Level::getItemsAt (this=0x80d4d58, pt=...)
at src/Level.cpp:519
519 map.setHasItem(pt, false);
(gdb) next
521 }
(gdb)
我已经尝试过多次重新编译,事先擦除了可执行文件和所有目标文件,但它仍然可以。
奇怪的是,如果我注释掉return语句并尝试编译,它只会给warning: no return statement in function returning non-void
。我原本以为在函数中没有提供return语句会返回一些编译错误,但我猜不是。
我意识到这不是很多,但有没有人知道为什么会这样?要检查什么?在这一点上,我甚至不知道从哪里开始寻找。
编辑:为了澄清,我正在使用-O0
进行编译。
根据tjm,即使使用-O0
编译器标志,我的gcc版本仍会使用RVO,所以这就是问题所在。谢谢你的帮助,伙计们。
答案 0 :(得分:6)
将此添加到GCC选项:-fdump-tree-nrv
以查看编译器的NRVO应用程序(您将获得一个扩展名为.nrv
的文件)。这仅适用于大于-O0
的优化级别。
如果没有优化,用复制构造函数或复制赋值运算符调用替换return
语句仍然是C ++前端转换,gdb
无法正常处理。
答案 1 :(得分:1)
我可以想到为什么可以跳过return语句的几个原因 - 这些都可能是这种情况吗?
该函数是否正常工作 - 被调用者是否得到了结果并继续其快乐的方式?
答案 2 :(得分:0)
map和pt是否正确分配并初始化了对象?
如果从第519行抛出异常,则该方法将不会正常返回。在这种情况下,当堆栈展开时,您可能希望下一行“执行”为第521行。
当代码执行导致“未定义行为”的事情时,我在Visual C ++中已经看到了很多这样的东西。我没有足够的g ++经验来了解观察到的行为是否相同。