1

What is the difference between the following two for-loops?

for(int i = 0; i < 5; i++)
{

}

and

for(int i = 0; i < 5;)
{
//End of whatever code to do.
 i++;
}

According to http://www.cplusplus.com/doc/tutorial/control/, there shouldn't be a difference. Yet when I run my code (the one below), depending on where the iter++ is, there is a difference.

In this program, I have a separate thread running to get an input. What happens when I move the iter++ to the bottom is that when a separate client connects to the server, I have to enter something into the cin stream before it responds.

When iter++ is at the top inside the for loop, this problem does not happen.

The reason why I want my iter++ to be at the bottom is so that when I receive a disconnect, I can delete the session in my map.

    for (iter = network->sessions.begin(); iter != network->sessions.end(); iter++)
{
    //bool Deleted = false;

    int data_length = network->receiveData(iter->first, network_data);

    if (data_length < 0) 
    {
        //no data recieved
        continue;
    }
    if (data_length == 0)
    {
        printf("Data closed GRACEFULLY LOL \n");
        continue;
    }

    int i = 0;
    while (i < (unsigned int)data_length) 
    {
        packet.deserialize(&(network_data[i]));
        i += sizeof(Packet);

        switch (packet.packet_type) {

            case INIT_CONNECTION:

                printf("server received init packet from client\n");

                char Buffer[100];
                //Buffer to hold char values of client id

                _itoa_s(client_id - 1, Buffer, 10);
                sendActionPackets(client_id - 1, Buffer);

                break;

            case ACTION_EVENT:

                printf("server received action event packet from client\n");

                break;


            case TALK:
                ProcessTalkLine(packet.Message, sizeof(packet.Message), iter->first);
                //sendTalkPackets(packet.Message,sizeof(packet.Message), iter->first);

                break;

            case DISCONNECTING:
                printf("I HAVE RECEIVED DC CONNECT /n");
                char theMessage[MAX_MESSAGE_SIZE];
                sprintf_s(theMessage, "%s has disconnected.", Usernames.find(iter->first)->second.c_str());
                Usernames.erase(iter->first);
                //network->sessions.erase(iter++);

                break;
            default:

                printf("error in packet types\n");

                break;
        }
    }
}

EDIT: Thanks to @Matt McNabb for pointing out that the continue would...well continue. I've put in my iter++ there as well, but the problem that it would not receive the messages until I put in something remains. If I left the iter++ inside the for loop, this problem isn't there.

6
  • 5
    Why do people always think it is more probable that the compiler is wrong, than they making some mistake? Either use a debugger or add a debug print right before the ++iter call in the second version(the one you have not included in the question). I bet you will notice that although you think it is always called some continue/break call skips it. Commented Nov 13, 2014 at 9:42
  • If network->sessions is a std::vector, then you can't use erase like you do in the outcommented line because it will invalidate the iterator. Commented Nov 13, 2014 at 9:42
  • @JoachimPileborg I know that, which is why I'm trying to put the i++ below. Commented Nov 13, 2014 at 9:48
  • @IvayloStrandjev Unfortunately, I really don't know why. I've already used VS debugger, but it seems as if it doesn't receive the send unless I cin something. This is also my first time running different threads at the same time. Commented Nov 13, 2014 at 9:49
  • You might want to read the erase reference I linked to in my comment, and see what erase returns. Commented Nov 13, 2014 at 9:58

4 Answers 4

6

When you continue it execute the third statement in the for . In your first case this increments i and in the second case it doesn't.

The loops are only the same if you do not use continue (or goto).

Sign up to request clarification or add additional context in comments.

4 Comments

Oh that makes sense. Thank you good sir for pointing out my mistake.
Unfortunately, it didn't fix the error that I need to input something before the program recognizes that a client has connected.
This is awkward. I restarted my VS and recompliled and it worked.
rebooting fixes MS products..:)
2

These two are not same:

for(int i = 0; i < 5; i++)
{
    if (some_condition)
        continue;
}

and

for(int i = 0; i < 5;)
{
    if (some_condition)
        continue;

    //End of whatever code to do.
    i++;
}

Comments

1
for(int i = 0; i < 5; i++)
{
    if (condition)
        continue;
    //Your Code
}

In above for loop, on condition is true then loop will continue without traversing the line below. But the i value will be definitely incremented.

for(int i = 0; i < 5;)
{
    if (condition)
        continue;

    //Your Code
    i++;
}

In second for loop behave same way as previous except on continue the value of i will not be incremented.

In you case if you want surely to put itr++ at the bottom then write like following,

for(int i = 0; i < 5;)
{
    if (condition)
        goto incrementPoint; //Use goto instead of continue.

    //Your Code
    incrementPoint: i++;
}

Comments

0

to really see the difference consider the code a compiler will generally generate for a for loop: for(i= initial_value; i<max value; i=i+increment)

NOTE: this is pseudocode and ignores all compiler optimizations

**stat_for_loop**:
      execute instructions
      i=i+increment
      if i<max_value
         goto **stat_for_loop**

when you add a continue statements inside the for loop the generally look like this:

**stat_for_loop**:
      execute instructions
      if(cond) 
         goto **next_iteration**
      execute instructions   
**next_iteration**:
      i=i+increment

      if i<max_value
           goto **stat_for_loop**

You can clearly see that if you ignore the iterator incrementation in the for loop and you decide to increment it manually in the for block (like you would do for a while loop), depending on when you add a continue statement, the generated code will be different, hence the execution path will be different

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.