ChaosDev
ChaosDev

Reputation: 35

C++ return statement strange behaviour?

I've discovered something new (for myself) about return statements. In combination with for and if this force debugger to not return control from function and proceed to the next statements, instead, it stacks inside function and repeat for until condition will not be true. For example:

struct Position
{
    int position;
    int value;
};

vector<Position> find_all(vector<Position>& v, int value)
{
    vector<Position> res;
    for (auto p = v.begin(); p != v.end(); ++p)
        if (p->value == value)
            res.push_back(*p);

    return res;
}

int main()
{
    vector<Position> v { { 0, 0 }, { 1, 1 }, { 2, 0 }, { 3, 3 },
                         { 4, 4 }, { 5, 6 }, { 6, 0 }, { 7, 2 } };
    find_all(v, 0); 
    cin.get();
    return 0;
}

If you set debugger to return res; and start debugging code, when you step into this method the function will continue executes inside function until for loop ends, instead return. If you set curly brackets in if statements return will work normal.

I do not understand please someone explain me what happens and why? Im using VisualC++ but found this type of return usage in Stroustrup book.

Upvotes: 0

Views: 192

Answers (1)

cdmh
cdmh

Reputation: 3344

This is symptomatic of source-level debugger trying to track execution of machine code back to the source code. The for loop has a condition p != v.end() which is actually a while condition and is evaluated at each iteration. This condition evaluation is typically at the end of the loop (in MSVC at least). In your example, there is no code at the end of the loop, so the debugger shows the "current line" as the statement after the loop, which is the return res; line.

If you put curly braces around the for loop body, with the closing curly on a new line, then the debugger will have a line of code to associate with the condition, and you will see expected behavior.

vector<Position> find_all(vector<Position>& v, int value)
{
    vector<Position> res;
    for (auto p = v.begin(); p != v.end(); ++p)
    {
        if (p->value == value)
            res.push_back(*p);
    }

    return res;
}

Remember that the debugger shows an approximation of the current line. In Debug mode, this is usually pretty accurate, but there are cases such as this where it "looks odd". If you try stepping through a Release build, with optimizations, you'll notice the "current line" appears to jump around all over.

Upvotes: 5

Related Questions