Значение локальной переменной в одной функции, используемой в другой функции (c программирование)
#include<stdio.h>
void bar()
{
int a=4;
}
void foo()
{
int a;
printf("%d",a);
}
int main()
{
bar();
foo();
}
Я уверен, что вышеприведенная программа выдает результат в виде некоторого ненужного значения (вот что происходит, когда я компилирую и запускаю). Но я прочитал в статье, что некоторые компиляторы могут выдавать результат как 4. Было дано объяснение, что оно связано со стеком активации и кадрами активации. Я не понимаю Это что-то вроде значения функции int a=4 из bar() хранится где-то в стеке активации для будущего использования? Я запутался!!
4 ответа
Чтобы быть ясным, возможно, что foo's a в конечном итоге будет с 4 в этом баре, который установлен там (ничего общего с ними, имеющими одно и то же имя BTW). Но это сильно зависит от машин компилятора и т. Д.
То, что вы на самом деле делаете (в foo), это "неопределенное поведение", вы используете без указания значения. Неопределенный означает, что компилятор может делать что угодно, форматировать жесткий диск, печатать любое случайное значение, включая дату рождения ваших лучших друзей, или он может напечатать 4.
Почему это может быть 4, потому что построение стековых фреймов во многих системах приведет к тому, что тактовая запись 4 будет записана в адрес и будет считывать его обратно. Эти 2 функции имеют одинаковые параметры, тип возвращаемого значения и количество локальных элементов, поэтому возможно, что первый локальный элемент будет размещен в одной и той же ячейке памяти. Вот почему вы читаете, что они могут иметь одинаковое значение, но это случайно, а не дизайн
Кстати, вы получили 4 или нет, вероятно, нет
Не беспокойтесь о том, что могут сделать некоторые компиляторы. Это называется "неопределенное поведение". Всегда убедитесь, что вы инициализируете свои переменные так, как хотите.
Опять же, бессмысленно пытаться "понять", потому что в этом нет логики, и это определенно не "ожидаемое поведение". Но вполне возможно, что некоторые компиляторы будут повторно использовать регистр на процессоре, если функции встроены, так что да, это может произойти. Если вы как-то обеспокоены тем, что кто-то запускает функцию после вашей и "крадет ваше значение", просто установите его на ноль, прежде чем выйти из вашей функции. Но это не "Лучшие практики".
Другими словами, даже если вторая функция использует 'b' вместо a, в ней может быть 4, если они повторно используют пространство памяти. Или какой-то другой компилятор может на самом деле предварительно распределить в алфавитном порядке, поэтому будет работать только "a". Опять же, это неопределенное поведение.
Функция foo
использует неинициализированную переменную. В этой ситуации компилятор может делать то, что ему нравится. На практике вы можете получить переменную, которая ранее была помещена в стек в уже не существующем фрейме. Как вы говорите, это может быть 4, но вместо этого может быть что угодно. Никогда не полагайтесь на такое поведение... это может быть на 99% надежно, но с 100-й попытки ошибиться.
Хотя две переменные имеют одинаковое имя, они хранятся по разным адресам, а вторая a
это было инициализировано компилятором, возможно, имеет другое значение, чем 4.
Вот так выглядит a
, но после компиляции эти две локальные переменные отличаются и не могут быть одинаковыми.