Q:

Inconsistent undefined behavior

For a class, I wanted to demonstrate undefined behavior with goto to the students. I came up with the following program:
#include <stdio.h>

int main()
{
        goto x;

        for(int i = 0; i < 10; i++)
                x: printf("%d\n", i);

        return 0;
}

I would expect the compiler (gcc version 4.9.2) to warn me about the access to i being undefined behavior, but there is no warning, not even with:
gcc -std=c99 -Wall -Wextra -pedantic -O0 test.c

When running the program, i is apparently initialized to zero. To understand what is happening, I extended the code with a second variable j:
#include <stdio.h>

int main()
{
    goto x;

    for(int i = 0, j = 1; i < 10; i++)
            x: printf("%d %d\n", i, j);

    return 0;
}

Now the compiler warns me that I am accessing j without it being initialized. I understand that, but why is i not uninitialized as well?

A:

Undefined behavior is a run-time phenomenon. Therefore it is quite rare that the compiler will be able to detect it for you. Most cases of undefined behavior are invoked when doing things beyond the scope of the compiler.
To make things even more complicated, the compiler might optimize the code. Suppose it decided to put i in a CPU register but j on the stack or vice versa. And then suppose that during debug build, it sets all stack contents to zero. 
If you need to reliably detect undefined behavior, you need a static analysis tool which does checks beyond what is done by a compiler.

