Будет ли ценность жить постоянно, когда нет ссылки на нее?
Предположим, что минимальный код:
#include <stdio.h>
char character = 'c';
int main (void)
{
char character = 'b';
printf("The current value of head is %c", character);
}
Я переписывал character
в main
,
Тогда что случилось с c
? Будет ли он автоматически уничтожаться или постоянно жить в памяти?
Этот комментарий нажимает на меня: "переменные в C - не что иное, как именованные фрагменты памяти".
Ответы
Ответ 1
" Затенение " глобальной переменной character
скрывает переменную от main
функции, но она все равно будет частью программы.
Если character
переменная была объявлена как static
, тогда компилятор может предупредить, что character
переменная никогда не используется, и character
будет оптимизирован.
Однако character
переменная не объявляется как static
; компилятор предполагает, что переменная character
может быть получена извне и сохранить переменную character
в памяти.
EDIT:
Как отметил @Deduplicator, оптимизация компоновщика и настройки могут опустить переменную из окончательного исполняемого файла, если это разрешено. Однако это краевой случай, который не произойдет "автоматически".
Ответ 2
У вас есть две отдельные переменные с именем character
: one в области с файлом, установленным в 'c', чье жизненное время - это время жизни программы, а одно в main
наборе - 'b', чье время жизни - это его область действия.
Определение character
в main
маскирует определение в области файла, поэтому доступно только последнее.
Ответ 3
Дополнение к другим ответам:
Попробуйте это, и вы поймете:
#include <stdio.h>
char character = 'c';
void Check()
{
printf("Check: c = %c\n", character);
}
int main(void)
{
char character = 'b';
printf("The current value of head is %c\n", character);
Check();
}
Ответ 4
Он будет жить (пока программа не умрет, как и любая переменная статического хранилища), и вы все равно можете добраться до нее:
#include <stdio.h>
char character = 'c';
int main (void)
{
char character = 'b';
printf("The current value of head is '%c'\n", character);
{
extern char character;
//in this scope, overrides the local 'character' with
//the global (extern?) one
printf("The current value of head is '%c'\n", character);
}
printf("The current value of head is '%c'\n", character);
}
/*prints:
The current value of head is 'b'
The current value of head is 'c'
The current value of head is 'b'
*/
Локальная декларация extern не работает надежно/переносимо для static
глобалов, хотя вы все равно можете добраться до них через указатели или через отдельную функцию.
(Почему не static char character='c'; int main(){ char character='b'; { extern char character; } }
надежный с глобальным static
?
6.2.2p4 кажется, что он хочет заставить его работать и для статики, но формулировка неоднозначна (предварительная декларация не имеет связи, а другая имеет статическую/внешнюю связь, так что теперь?).
6.2.2p4:
Для идентификатора, объявленного с помощью спецификатора класса хранения extern в области видимости, в которой видна предварительная декларация этого идентификатора, 31), если предыдущее объявление указывает внутреннюю или внешнюю связь, связь идентификатора с последующим объявлением такая же, как связь, указанная в предыдущем объявлении. Если ни одно предварительное объявление не отображается, или если в предыдущем объявлении не указана ссылка, то идентификатор имеет внешнюю привязку.
Мой clang 6.0.0 принимает его со static char character='b';
но мой gcc 7.3.0 - нет.
Благодаря Эрик Postpischil за указание неоднозначной возможности этого быть пригодно для работы с static
тоже. )
Ответ 5
После объявления character
в main
любая ссылка на character
в этой функции относится к этой, а не к глобальной. Мы называем это затенением.
Что касается эффекта на память, вы не можете сказать из-за правила as-if, принятого языком: компилятор может оптимизировать
#include <stdio.h>
int main()
{
printf("The current value of head is b");
}
например.
Ответ 6
#include <stdio.h>
char character = 'c';
int main (void)
{
char character = 'b';
printf("The current value of head is %c\n", character);
printc();
}
void printc()
{
printf("%c", character);
}
Все ясно. Он не разрушен, он просто затенен.
Выход: текущее значение головки равно b
с
Ответ 7
Нормальный, глобальная переменная останется. Поскольку ваша локальная переменная только затеняет имя, она не влияет на хранилище.
Но это также может зависеть от настроек компоновщика. Linker может оптимизировать недопустимую глобальную переменную.
Ответ 8
Хотя глобальные переменные существуют с самого начала до конца выполнения программы, они не доступны автоматически.
Доступна глобальная переменная, начиная с местоположения в файле, где глобальная переменная определяется или объявляется до конца файла.
Если в области функций задана переменная с тем же именем, глобальная переменная будет существовать, но не будет доступна.