Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

my program skips over a return statement

Tags:

c++

g++

My program has this function:

    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;
    }

This compiles fine (I'm using g++, my gcc version is 4:4.4.1-1ubuntu2), but when I run the program it skips right over the return statement.

I stepped through with gdb, setting a breakpoint at the previous line, and got this:

Breakpoint 1, yarl::level::Level::getItemsAt (this=0x80d4d58, pt=...)
at src/Level.cpp:519
519                 map.setHasItem(pt, false);
(gdb) next
521             }
(gdb) 

I've tried recompiling from scratch several times, erasing the executable and all the object files beforehand, and it still does it.

Strangely, if I comment out the return statement and try to compile, it only gives warning: no return statement in function returning non-void. I would have thought not providing a return statement in a function that returns something would be a compiler error, but I guess not.

I realize this is not much to go on, but does anyone have an idea why this is happening? What to check for? At this point I don't even know where to start looking.

EDIT: for clarification, I'm compiling with -O0.

According to tjm, my version of gcc will still use RVO even with a -O0 compiler flag, so that was the problem after all. Thanks for your help, guys.

like image 327
Max Avatar asked Jul 10 '10 21:07

Max


2 Answers

C++ source code does not have to correspond to resulting object code one-to-one as long as the behavior is preserved. What's happening here is that the compiler rearranges the code, and probably invokes Return Value Optimization.

Edit:

Add this to the GCC options: -fdump-tree-nrv to see NRVO applications by the compiler (you'll get a file with .nrv extension). This only works with optimization level greater then -O0.

Without optimization, replacing the return statement with copy constructor or copy assignment operator call is still a C++ front-end transformation, which is not gracefully handled by the gdb.

like image 161
Nikolai Fetissov Avatar answered Sep 28 '22 19:09

Nikolai Fetissov


I can think of a couple of reasons why the return statement may be skipped over - could any of these be the case?

  • An exception is thrown on line 519. This sounds very unlikely given line 521 is hit.
  • The compiler has optimised away the return statement line - are you debugging a proper debug build (no optimisations enabled)?

Does the function work fine - does the callee get the result back and carry on its merry way?

like image 38
Will A Avatar answered Sep 28 '22 18:09

Will A