Глобальные инициализированные переменные, объявленные как «const», переходят в текстовый сегмент, а объявленные как «статические» - в сегмент данных. Зачем? - PullRequest
5 голосов
/ 17 октября 2010
#include <stdio.h>

const int str[1000] = {0};

int main(void)
{
    printf("arr is %d\n", str[0]);
    return 0;
}

Имеет следующий вывод:

[-exercises/adam/stack2]:size a.out
   text    data     bss     dec     hex filename
   5133     272      24    5429    1535 a.out

Принимая во внимание:

#include <stdio.h>

static int str[1000] = {0};

int main(void)
{
    printf("arr is %d\n", str[0]);
    return 0;
}

Имеет следующий вывод:

[-exercises/adam/stack2]:size a.out
   text    data     bss     dec     hex filename
   1080    4292      24    5396    1514 a.out

Когда массив неинициализирован - он снова переходит к текстовому сегменту для «const» и к BSS для «статического».

Переменная является глобальной и должна быть доступна из любого места исполняемого файла, частью которого она является (из-за отсутствия «статичности»), но учитывая ее переменную, я не знаю, почему она помещается в текстовый сегмент вместо сегмента данных

Ответы [ 5 ]

7 голосов
/ 17 октября 2010

С Kernighan & Ritchie :

static является спецификатором класса хранения.Другие спецификаторы класса хранения: auto, register, extern & typedef.Статический спецификатор дает объявленным объектам статический класс хранения.Статическое объявление, применяемое к внешней переменной или функции, ограничивает область действия этого объекта остальной частью компилируемого исходного файла.Статические объекты могут быть локальными по отношению к блоку или внешними по отношению ко всем блокам, но в любом случае сохраняют свои значения при выходе и повторном входе в функции и блоки.

Принимая во внимание,

const является классификатором типа.Спецификатор другого типа является изменчивым.Цель const - объявить объекты, которые могут быть помещены в постоянную память, и, возможно, расширить возможности для оптимизации.

Полагаю, можно сделать вывод, что оба эти ключевых слова служат различным целям;что из const переменных, находящихся в text/code segment, совершенно ясно из его назначения.

6 голосов
/ 17 октября 2010

Ты в замешательстве.Нет дихотомии между const и static;оба независимы.Предполагая, что все данные инициализированы, и static const, и внешний (глобальный) const войдут в text, и оба - const -квалифицированный static и не-const -квалифицированный внешний - будут data.

Что касается bss, современные двоичные форматы, такие как ELF, фактически имеют отдельный bss для данных с постоянным и непостоянным нулем.Вывод команды size просто не показывает ее.

3 голосов
/ 17 октября 2010

Чтобы защита памяти работала.Любая попытка записи в const вызовет ошибку по умолчанию.

1 голос
/ 17 октября 2010

Помещая данные const в текстовый раздел, компилятор пытается принудительно применить constness.

Имейте в виду, что раздел TEXT загружается в страницы памяти, помеченные только для чтения в таблицах страниц MMU. Это необходимо для предотвращения случайного повреждения кода. Помещая константные данные в одну и ту же область, эти данные также доступны только для чтения. Любые записи в эти данные будут вызывать исключения.

Неинициализированные данные, объявленные как статические, попадут в сегмент BSS, чтобы сэкономить место в исполняемом файле. Эта область выделяется в памяти загрузчиком. Инициализированные данные, объявленные как статические, попадут в сегмент DATA, предназначенный для чтения и записи.

1 голос
/ 17 октября 2010

Когда вы объявляете переменную const, вы говорите компилятору, что вы никогда не собираетесь изменять его значение.С другой стороны, с объявлением static, сделанным в области видимости файла, вы сообщаете компилятору, что эта переменная является частной по отношению к модулю компиляции, в котором она была объявлена, но функции в этом модуле компиляции все еще могут изменятьпеременная.

Как упоминает Оли в своем ответе , поиск переменной const в сегменте text позволяет системе обеспечить защиту доступа к памяти.Кроме того, рассмотрим встроенную систему, в этом случае сегмент text обычно записывается на флэш-память и поэтому не может быть изменен.Сегменты data, bss и т. Д. Находятся в оперативной памяти, и их изменение разрешено.

...