Shadowing an iterator inside a for loop has undefined (?) behaviour in C - Stack Overflow

When shadowing i inside the for loop, the following code#include <stdio.h>int main(){for (int i

When shadowing i inside the for loop, the following code

#include <stdio.h>

int main()
{
    for (int i = 1; i < 5; i++) {
        printf("%d", i);
        int i = i;
        printf("%d ", i);
    }
}

outputs:

10 20 30 40

From my understanding of shadowing, there should've been a new i created with the value equal to the previous i. This means the output I expected would've been:

11 22 33 44

Furthermore, the code seems to store the new i value if you increment it.

#include <stdio.h>

int main()
{
    for (int i = 1; i < 5; i++) {
        printf("%d", i);
        int i = i + 2;
        printf("%d ", i);
    }
}

this outputs:

12 24 36 48

Seemingly, i is not being redeclared every iteration - it works like a variable that was initially 0 and then was incremented every iteration.

What's actually happening here? How do you predict the behaviour?

When shadowing i inside the for loop, the following code

#include <stdio.h>

int main()
{
    for (int i = 1; i < 5; i++) {
        printf("%d", i);
        int i = i;
        printf("%d ", i);
    }
}

outputs:

10 20 30 40

From my understanding of shadowing, there should've been a new i created with the value equal to the previous i. This means the output I expected would've been:

11 22 33 44

Furthermore, the code seems to store the new i value if you increment it.

#include <stdio.h>

int main()
{
    for (int i = 1; i < 5; i++) {
        printf("%d", i);
        int i = i + 2;
        printf("%d ", i);
    }
}

this outputs:

12 24 36 48

Seemingly, i is not being redeclared every iteration - it works like a variable that was initially 0 and then was incremented every iteration.

What's actually happening here? How do you predict the behaviour?

Share Improve this question edited Mar 6 at 17:42 wohlstad 30.2k17 gold badges61 silver badges94 bronze badges asked Mar 6 at 17:26 LuminLumin 4831 gold badge11 silver badges24 bronze badges 7
  • 6 Relevant: stackoverflow/questions/11186261/why-is-int-i-i-legal. Bottom line: int i = i; actually assigns i to itself (not the i of the loop`) and accessing it is UB. – wohlstad Commented Mar 6 at 17:29
  • @wohlstad that's talking about using a variable before it's initialised. But when you take int i = i here does the RHS refer to the for loop iterator or is it already shadowing there? – Lumin Commented Mar 6 at 17:31
  • 2 Since i is in scope within its own initialization, the RHS must be the "new" i which shadows the outer one. – Nate Eldredge Commented Mar 6 at 17:34
  • @Lumin RHS is the new shadowing i. It is already in scope, othertwise a bare int i = i; wouldn't be legal. – wohlstad Commented Mar 6 at 17:34
  • MSVC issues a warning for both codes: uninitialized local variable 'i' used for the line int i = i; and int i = i + 2;. – Weather Vane Commented Mar 6 at 17:39
 |  Show 2 more comments

2 Answers 2

Reset to default 4

A statement like:

int i = i;

Is generally legal, but unlike what you expect, will attempt to assign i to itself (and not to the i from the for loop).

This is because the new i is already in scope (otherwise a bare int i=i; without a previous i wouldn't be legal).

Afterwards you access this i which causes UB (undefine-behavior), which means that any result that you see is valid.

The same applies similarly to the case with:

int i = i + 2;

More about statements like int i = i; can be found here (that post is for C++ but is relevant for C as well).

As mentioned elsewhere, int i = i; attempts to initialize i from itself, but the latter i refers to the new i, not the old one, and it has an unspecified value here, and, subject to certain conditions, this causes the program to have undefined behavior.

If you do wish to initialize a new i from the old one, you can do this with an intermediate variable:

#include <stdio.h>


int main(void)
{
    for (int i = 1; i < 5; i++)
    {
        printf("%d", i);
        int t = i, i = t;
        printf("%d ", i);
    }
    printf("\n");
}

Where t is initialized, the outer i is visible, and then the new i is initialized from t.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744958997a4603373.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信