2

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.

101010
  • 41,839
  • 11
  • 94
  • 168
  • 1
    Your test of the `for` is "suitable". Why wouldn't it be? You should see `0` through `4` printed because the 3rd expression in the `for` is performed at the end of the loop. C programming documentation will explain this. There are a jillion references online if you search, but here's just [one example](https://en.wikipedia.org/wiki/For_loop). Your `while` example starts with an uninitialized `j` variable. – lurker Oct 31 '15 at 22:45
  • @lurker Thanks for catching that. I fixed it. –  Oct 31 '15 at 22:46

7 Answers7

2

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++;
}
Peter
  • 35,646
  • 4
  • 32
  • 74
1

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).

101010
  • 41,839
  • 11
  • 94
  • 168
  • Examining compiler output is not a sure-fire way to determine what is required of the language (i.e. what the standard requires). It only determines what the particular compiler does. – Peter Oct 31 '15 at 22:58
  • @Peter fair enough. I added the standard justification. – 101010 Oct 31 '15 at 23:09
  • @101010 What is this "standard" that you quote from and where can I find it? –  Oct 31 '15 at 23:13
  • @gabacabriel You have to buy it from [here](http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=57853) – 101010 Oct 31 '15 at 23:18
  • The "standard" refers to the ISO standard that describes the C programming language (and library). First version is ANSI X3.159-1989 "Programming Language C.". This was released (same content, minor topping and tailing differences) in 1990 as ISO/IEC 9899:1990, with subsequent updates ISO/IEC 9899:1999 and (in 2011) ISO/IEC 9899:2011. You can buy copies through www.iso.org. – Peter Oct 31 '15 at 23:28
1

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.

Community
  • 1
  • 1
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
1
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;
}
lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
1

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
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

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!

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
zuko32
  • 239
  • 1
  • 9
  • Although when possible, `for` loops are preferred because the increment of the loop variable is guaranteed. – Iharob Al Asimi Oct 31 '15 at 22:48
  • 1
    Yeah, you are right! It's just that while loop is more controllable in this specific thing. I didn't mean that while loop is better. The loop that one will use differs from situation to situation and a lot of times it is a matter of preference. – zuko32 Oct 31 '15 at 22:52
0

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.

badjr
  • 2,166
  • 3
  • 20
  • 31