my program skips over a return statement
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.
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
.
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?
Are map and pt correctly allocated and initialized objects?
If an exception is thrown from line 519 then the method won't return normally. In this case you might expect the next line "executed" to be line 521 as the stack unwinds.
I've seen quite a lot of this in Visual C++ when the code does something that results in "undefined behavior". I don't have enough experience with g++ to know if the observed behavior is the same.
精彩评论