During debugging my program jumps to nearest while statement without break or continue [C++]

62 views Asked by At

When running my C++/Qt5 program under gdb I experienced what seems like an impossibility:

while(totalAvailable > (sizeof(quint32)+sizeof(quint16))){  
    if(nullptr!=c){
        // POINT-A
        qDebug()<<rct<<"Courier message with ID "<<octomy_message_type_int<<" was received with name "<<c->getName()<<" and "<<bytesAvailable<<" bytes available";
        const quint16 bytesSpent=c->dataReceived(*ds, bytesAvailable);
        const int left=bytesAvailable-bytesSpent;
        totalAvailable-=bytesSpent;
        if(left>=0){
            if(left>0){
                ds->skipRawData(left);
                totalAvailable-=left;
            }
            else{
                // POINT-B
                qDebug()<<rct<<"LOLBOB";
            }
        }
        else{
            qWarning()<<"BAR";
            return;
        }
    }
    else{
        qWarning()<<"FOO";
        return;
    }
}

In short, when I step from //POINT-A to //POINT-B everything is as expected, but as soon as I step past //POINT-B debugger jumps up to the first line of the program (while statement). But there are no break or continue or other flow-altering statements in the code. How is this possible?

I have tried rebuilding my code from scratch to eliminate a bogus linkage or similar problems, but the bug is reproducible still.

Any input is welcomed.

4

There are 4 answers

1
Aganju On BEST ANSWER

At POINT-B, you are inside an else, which is inside an if, which is inside an if. Once this else is done, there is nothing more to do in the whole tree.

Where would you expect the pointer to jump to??

Technically, it would go to the closing bracket two lines behind POINT-B, then to the closing bracket three lines behind POINT-B, and then to closing bracket eight lines behind POINT-B, and then to the closing bracket at the very end. All those do nothing, so they are skipped.

0
Sam Varshavchik On

Take a paper and pencil, and diagram the logical flow of this chunk of code.

You will make a surprising discovery that the only statement that could possibly execute, after the statement you marked "POINT B", is the condition at the beginning of the while loop. After executing the "POINT B" statement, there are no more statements to execute in the body of the loop, so execution winds back to the while condition, for the next iteration.

0
AudioBubble On

Basically the loop just re-iterates. I believe it is functioning as it is supposed to. From Point-A the control goes like such:

If no.1 (Point-A) -> If no.2 -> Else corresponding to If no.3 -> back to end of If no.2 -> back to end of If no.1 -> back to end of while loop.

As the loop is over, the execution checks the loop's condition, (if it is satisfied) re-iterates, and eventually you reach Point-A again.

while()
{
    if() // If no.1
    {

    // Point-A *****************************

        if() // If no.2
        {
            if() // If no.3
            {
            }
            else()
            {

                // Point-B *****************

            }
        }
        else
        {
        }
    }
    else
    {
    }
}

To improve debugging and readability, do not keep nesting if blocks or loops - It is very hard to trace the execution.

0
Spock77 On

Look if you write it this equivalent way:

while(totalAvailable > (sizeof(quint32)+sizeof(quint16))){  

    if(nullptr==c){
    qWarning()<<"FOO";
        return;
    }

    // POINT-A
    qDebug()<<rct<<"Courier message with ID "<<octomy_message_type_int<<" was received with name "<<c->getName()<<" and "<<bytesAvailable<<" bytes available";
    const quint16 bytesSpent=c->dataReceived(*ds, bytesAvailable);
    const int left=bytesAvailable-bytesSpent;
    totalAvailable-=bytesSpent;
    if(left<0){
        qWarning()<<"BAR";
        return;    
    }

    if(left>0){
        ds->skipRawData(left);
        totalAvailable-=left;
    }
    else{
        // POINT-B
        qDebug()<<rct<<"LOLBOB";
    }    
}