user5405027
user5405027

Reputation:

When does the loop variable in a for loop get updated?

Does the loop variable get updated before beginning the for loop? or at the end of each iteration of the for loop?

I tried to write a test code to figure it out myself, but I'm not sure if it is a suitable test.

#include <stdio.h>

int main(void)
{
  int i;

  for (i = 0; i < 5; i++) // does i++ happen here
    {
      printf("%d\n", i); // or does it happen after this is executed?
    }

  return 0;
}

With this while loop, it's clear where the variable updates:

#include <stdio.h>

int main(void)
{
  int j;

  j = 0;
  while (j < 5)
    {
      printf("%d\n", j);
      j++; // j updates here
    }

  return 0;
}

Thanks in advance.

Upvotes: 2

Views: 2156

Answers (7)

chux
chux

Reputation: 153498

The only differences with OP for / while examples are what happens with a break or continue and scope rules.

for ( clause-1 ; expression-2 ; expression-3 ) statement

acts like

{
  clause-1;
  while (expression-2) {
    {
      statement;
      // Should the statement contain a `continue` or `break`, then flow jumps as indicated.
      // a `continue` goes to continue_label:
      // a `break` goes to break_label:
   }
    continue_label:
    expression-3;
  }
  break_label:
}

The extra outer {} needed for scope: Should clause-1 be int x = 1; that is not the same as

  int x = 1;
  while (expression-2) {

but like

{
  int x = 1;
  while (expression-2) {

The innermost {} is also needed for scope. Examine the following code's output sequence and address of the 3 js.

int main(void) {
  int j;
  printf("1 %p\n", (void*) &j);
  for (int j = 0; 
       printf("2 %p\n", (void*) &j), j < 3;
       j++, printf("4 %p\n", (void*) &j)) {
    int j;
    printf("3 %p\n", (void*) &j);
  }
  return 0;
}

1 0x28ac1c
2 0x28ac18
3 0x28ac14
4 0x28ac18
2 0x28ac18
3 0x28ac14
4 0x28ac18
2 0x28ac18
3 0x28ac14
4 0x28ac18
2 0x28ac18

Upvotes: 1

lost_in_the_source
lost_in_the_source

Reputation: 11237

for (expr1; expr2; expr3)
    code;

is equivalent to

expr1;
while (expr2) {
    code;
    expr3;
}

So yes, the increment happens after body is completed. Here is the implementation of strlen

int strlen(char *s)
{
    int i;

    for (i = 0; s[i]; ++i)
        ;

    return i;
}

that would be the same as:

int strlen(char *s)
{
    int i;

    i = 0;
    while (s[i])
        ++i;

    return i;
}

Upvotes: 1

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42899

According to the standard ISO/IEC 9899:2011 Information technology -- Programming languages -- C §6.8.5.3/1 The for statement (Emphasis Mine):

The statement

for ( clause-1 ; expression-2 ; expression-3 ) statement

behaves as follows: The expression expression-2 is the controlling expression that is evaluated before each execution of the loop body. The expression expression-3 is evaluated as a void expression after each execution of the loop body. If clause-1 is a declaration, the scope of any identifiers it declares is the remainder of the declaration and the entire loop, including the other two expressions; it is reached in the order of execution before the first evaluation of the controlling expression. If clause-1 is an expression, it is evaluated as a void expression before the first evaluation of the controlling expression.137)

Therefore the increment is taking place at the end of each iteration of the for loop.

You can also see this in the following example. A for loop most likely is materialized by the compiler like a goto statement. Consider the following piece of code:

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

The assembly code produced by this code is:

main:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    $0, -4(%rbp)
.L3:
    cmpl    $4, -4(%rbp)
    jg  .L2
    addl    $1, -4(%rbp)
    jmp .L3
.L2:
    movl    $0, %eax
    popq    %rbp
    ret

LIVE DEMO

If you focus at .L3 (i.e., the for loop) you'll notice the statement

addl    $1, -4(%rbp)

which is where the increment is taking place (i.e., ++i). After that command there's the jump back to .L3 (i.e., next iteration).

Upvotes: 1

Nick is tired
Nick is tired

Reputation: 7055

Despite what I previously answered, I was speaking nonsense, I recommend that you look at: postfix and prefix increment operator in a for loop

Essentially what the above post boils down with regards to your question is that the incrementation occurs at the END of the pass of the loop.

Upvotes: 1

Peter
Peter

Reputation: 36597

The expression i++ will be evaluated after the loop body completes.

Functionally, a for loop of the form

for (i = 0; i < 5; i++)
{
  printf("%d\n", i);
}

is equivalent in effect to;

i = 0;
while (i < 5)
{
    {
         printf("%d\n", i);
    }
    i++;
}

Upvotes: 2

badjr
badjr

Reputation: 2286

The i++ happens after the body of the for loop. According to the GNU C Reference Manual,

 for (initialize; test; step)
   statement

The for statement first evaluates the expression initialize. Then it evaluates the expression test. If test is false, then the loop ends and program control resumes after statement. Otherwise, if test is true, then statement is executed. Finally, step is evaluated, and the next iteration of the loop begins with evaluating test again.

Upvotes: 0

zuko32
zuko32

Reputation: 239

In the for loop, the increment gets done after every iteration.
The while loop is more controllable in that and you can do it in whatever place you want!

Upvotes: 0

Related Questions