Будет ли ценность жить постоянно, когда нет ссылки на нее?

Предположим, что минимальный код:

#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

Хотя глобальные переменные существуют с самого начала до конца выполнения программы, они не доступны автоматически.

Доступна глобальная переменная, начиная с местоположения в файле, где глобальная переменная определяется или объявляется до конца файла.

Если в области функций задана переменная с тем же именем, глобальная переменная будет существовать, но не будет доступна.