While playing with the code I’ve noticed a strange behavior that I do not know to explain the logic behind
int 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?
Answer
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) | ^