распределение памяти для глобальных символов, определенных в нескольких местах в C - PullRequest
0 голосов
/ 27 июня 2018

Для глобальных определений, которые имеют одно и то же имя, мы выделяем память для каждого из них? Будут ли линкеры влиять на то, как мы распределяем память для этих глобальных символов?

Вот что я подумал о возможных способах решения этой проблемы:

1. Сначала мы выделяем память для глобальных переменных, когда встречаем их в программе. (Каждое определение будет иметь память.) Затем компоновщики разрешат глобальные символы.

2.После того, как компоновщики разрешат глобальные символы с одинаковыми именами, определенными в нескольких местах, мы выделяем память только для одного определения.

Один из них правильный?

Пример:

b.c

#include <stdio.h>
#include "a.c"
void f(void);
int x = 15213;
int main()
{
  f();
  printf("x = %d\n", x);
  return 0;
}

a.c

#include <stdio.h>
int x;
void f()
{
  printf("x in f = %d\n", x);
  x = 15212;
}

Приведенный выше код скомпилирован и запущен без каких-либо ошибок или предупреждений. Вот что я получаю:

x in f = 0
x = 15212

У нас есть одно определение х в памяти или два?

Один быстрый вопрос, связанный с этим:

Глобальные и статические переменные хранятся в Сегменте данных (DS) при инициализации и начинаются с блока по символу (BSS) при неинициализации. Несмотря на то, что данные в BSS не инициализированы, они всегда будут иметь значение по умолчанию вместо значения мусора. Это правильно?

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Поскольку один из файлов C непосредственно #include -d в другом, они находятся в одной и той же единице перевода. (Между прочим, это не рекомендуется - программисты используются для заголовочных файлов с именами *.h, а не *.c, а для *.c файлов, которые компилируются самостоятельно.) Что касается компилятора, то Программист просто скопировал и вставил содержимое одного файла в другой. Существует предварительное объявление x, но только одно определение.

Если вы поместите объявление extern в отдельную единицу перевода и скомпилируете их в отдельные объектные файлы, только тот, который содержит определение int x = 15213;, выделит память, а не тот, который содержит объявление int x;. Запись extern int x; может помочь запомнить, что x определено в другом месте. Если вы напишите два определения x и попытаетесь связать их, компоновщик выдаст вам ошибку.

0 голосов
/ 27 июня 2018

Если каждый из двух файлов .c объявляет свой собственный глобальный int x в качестве примера, выделяются две разные переменные в памяти.

Обратите внимание, что они находятся в другой области видимости, поэтому символы не доступны из другого файла. То есть каждый файл всегда обращается к своему собственному int x по имени глобальной переменной «x».

Ваш компилятор должен пожаловаться, если вы попытаетесь extern глобальной переменной в любой исходный файл, где существует глобальная переменная с тем же именем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...