我的程序跳过return语句

时间:2010-07-10 21:44:39

标签: c++ g++

我的程序有这个功能:

    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,所以这就是问题所在。谢谢你的帮助,伙计们。

3 个答案:

答案 0 :(得分:6)

只要行为得到保留,C ++源代码就不必一对一地对应于生成的对象代码。这里发生的是编译器重新排列代码,可能会调用Return Value Optimization

编辑:

将此添加到GCC选项:-fdump-tree-nrv以查看编译器的NRVO应用程序(您将获得一个扩展名为.nrv的文件)。这仅适用于大于-O0的优化级别。

如果没有优化,用复制构造函数或复制赋值运算符调用替换return语句仍然是C ++前端转换,gdb无法正常处理。

答案 1 :(得分:1)

我可以想到为什么可以跳过return语句的几个原因 - 这些都可能是这种情况吗?

  • 在第519行引发异常。鉴于第521行被击中,这听起来非常不可能。
  • 编译器优化了return语句行 - 您是否正在调试正确的调试版本(未启用优化)?

该函数是否正常工作 - 被调用者是否得到了结果并继续其快乐的方式?

答案 2 :(得分:0)

map和pt是否正确分配并初始化了对象?

如果从第519行抛出异常,则该方法将不会正常返回。在这种情况下,当堆栈展开时,您可能希望下一行“执行”为第521行。

当代码执行导致“未定义行为”的事情时,我在Visual C ++中已经看到了很多这样的东西。我没有足够的g ++经验来了解观察到的行为是否相同。