While playing with the code I've noticed a strange behavior that I do not know to explain the logic behind
void foo(int n)
{
int m = n;
while (--n > 0)
{
switch (n)
{
case -1:
case 0:
for (int j = 0; j < m; ++j)
default:
printf(":-)");
break;
}
}
}
int main()
{
foo(10);
return 0;
}
I would expect the printf
to execute let's say 10
times. Then I saw it continues to run (imagine 100000 instead of 10) and supposed that the developers (VS) interpreted the printf
inside the for
(pretty expected), hence the output is made n
times for each entrance to switch
.
But then turned out j
was never initialized.
So my question is why ? Is this an undefined behavior? Is not this a, supposedly, standard code?
default
is just a label (address to where the code jumps if n
is not -1 or 0).
Thus when n
is not -1 or 0, the flow enters the body of the for
loop skipping the initialisation of j
. You can write the same code also as this, so it would be clearer what is happening here:
int m = n;
while (--n > 0)
{
switch (n)
{
case -1:
case 0:
for (int j = 0; j < m; ++j)
{
default: printf(":-)");
}
break;
}
}
(Note, as mentioned by @alagner in the comments, it won't compile with C++ compiler but perfectly compiles with C one so this is good enough to make my point and explain how the code looks).
So yes, since j
is uninitialised, it is undefined behaviour.
If you enable compiler warnings, it will warn you about it (https://godbolt.org/z/rzGraP):
warning: 'j' may be used uninitialized in this function [-Wmaybe-uninitialized]
12 | for (int j = 0; j < m; ++j)
| ^