Измените его, чтобы добавить второй вызов к printf
, и вы увидите значение, отличное от первого раза. Скомпилируйте его с включенными оптимизациями, и вы увидите другой набор значений. Сделайте что-нибудь со значением, и вы войдете в неопределенную территорию, что означает, что компилятор может вызывать демонов через носовые проходы.
В моей системе я вижу 50
, а затем 0
; с оптимизацией я вижу 0
и затем 32767
.
Если вы сделаете локальную переменную static
, вы можете вернуть ее адрес, поскольку он становится похожим на глобальный (но помните, что существует только один его экземпляр).
Когда функция возвращается, локальное хранилище, которое она использовала в стеке, теперь считается программой "неиспользуемой", поскольку стек больше не поднимается так высоко. Однако, как правило, значения все еще там, так как нет необходимости срочно их очищать. Память также все еще принадлежит программе, поскольку нет смысла возвращать память операционной системе по несколько байт за раз. Так что для вашего конкретного примера, при обстоятельствах, в которых вы его скомпилировали, указанная память все еще содержит значение 50
. Официально, однако, значение *p
равно неопределенно , и попытки использовать его приводят к поведению undefined .
Один существенный кризис языка C заключается в том, что, с одной стороны, он ничего не говорит о стеке и различных битах шестнадцатеричного ила, которые составляют работающий процесс; с другой стороны, необходимо понимать их, чтобы защитить себя от сбоев, переполнения буфера и неопределенного поведения. Просто помните, что вам повезло, что GCC предупреждает об этом.