Неопределенное поведение, как следует из названия, не определено. Компиляторам не нужно объяснять, почему они делают то, что делают, им не нужно последовательно делать одну вещь, и им не нужно иметь причину для того, что они делают.
Способ, которым компиляторы обычно обрабатывают неопределенное поведение, состоит в том, чтобы игнорировать его. Никогда не было разработчика GCC, который бы сел и сказал: «Давайте напишем некоторый код для того, как GCC обрабатывает неинициализированные переменные». Все, что с ними происходит, происходит в результате провала всего кода другого в GCC. Таким образом, новые версии компилятора могут делать разные вещи с неинициализированными переменными не потому, что компилятор обрабатывает их по-разному, а потому, что он никогда не обрабатывал их преднамеренно вообще .