Стандарт C даже не упоминает стек.Компилятор может оптимизировать переменные, когда они не нужны.В стандарте C нет абсолютно ничего, что подразумевало бы, что распечатки не должны быть ни равны, ни не равны.
На моем компьютере это проявляется в том, что выдается различный вывод в зависимости от уровня оптимизации:
$ gcc c.c
/tmp$ ./a.out
0x7ffd8733c3ac
0x7ffd8733c3a8
/tmp$ gcc c.c -O3
/tmp$ ./a.out
0x7fff4e91544c
0x7fff4e91544c
Фактически, первое «int x» все еще доступно, даже если его область действия отсутствует.
Доступ к переменной, которая вышла из области действия, вызывает неопределенное поведение , что означает, что все может случиться.Это включает в себя случай, когда программа работает, как предполагалось.
Вот вывод из вашего второго фрагмента с различными оптимизациями:
/tmp$ ./a.out
0x7ffd4df94864
0x7ffd4df94860
0x7ffd4df9485c
10 25 71
/tmp$ gcc c.c -O3
/tmp$ ./a.out
0x7ffc30b4e44c
0x7ffc30b4e44c
0x7ffc30b4e44c
0 0 71
Когда вы получаете различное поведение в зависимости от уровня оптимизации, этопочти 100% признак того, что в вашей программе есть что-то, что вызывает неопределенное поведение.Существует очень и очень малая вероятность того, что вы столкнулись с ошибкой в компиляторе.И кроме этих двух причин, я не могу думать ни о чем другом, что могло бы быть причиной.