Ответ 1
Как они хранятся, это деталь реализации (зависит от компилятора).
Например, в компиляторе GCC на большинстве машин в текстовом разделе помещаются переменные только для чтения, константы и таблицы перехода.
Интересно, где хранятся постоянные переменные. Находится ли он в той же области памяти, что и глобальные переменные? Или это в стеке?
Как они хранятся, это деталь реализации (зависит от компилятора).
Например, в компиляторе GCC на большинстве машин в текстовом разделе помещаются переменные только для чтения, константы и таблицы перехода.
В зависимости от сегментации данных, которой следует конкретный процессор, у нас есть пять сегментов:
Обратите внимание, что разница между сегментами данных и BSS заключается в том, что в первом хранятся инициализированные глобальные и статические переменные, а в последнем хранятся неинициализированные переменные.
Теперь, почему я говорю о сегментации данных, когда я просто должен сказать, где хранятся постоянные переменные... есть причина для этого...
Каждый сегмент имеет защищенную от записи область, в которой хранятся все константы.
Например:
Подводя итог, можно сказать, что "const" - это просто КВАЛИФЕР данных, что означает, что сначала компилятор должен решить, в каком сегменте должна быть сохранена переменная, а затем, если переменная является константой, то она может быть сохранена в защищенной от записи области этот конкретный сегмент.
Рассмотрим код:
const int i = 0;
static const int k = 99;
int function(void)
{
const int j = 37;
totherfunc(&j);
totherfunc(&i);
//totherfunc(&k);
return(j+3);
}
Как правило, i
может храниться в текстовом сегменте (это переменная только для чтения с фиксированным значением). Если он не находится в текстовом сегменте, он будет храниться рядом с глобальными переменными. Учитывая, что он инициализирован нулем, он может находиться в разделе "bss" (где обычно назначаются нулевые переменные) или в разделе "данные" (где обычно назначаются инициализированные переменные).
Если компилятор убежден, что k
не используется (что может быть, поскольку он является локальным для одного файла), он может вообще не отображаться в объектном коде. Если вызов totherfunc()
, который ссылается на k
, не был прокомментирован, тогда k
должен быть назначен адрес где-то - он, вероятно, будет в том же сегменте, что и i
.
Константа (если она является константой, является ли она еще переменной?) j
, скорее всего, появится в стеке обычной реализации C. (Если вы спрашивали в группе новостей comp.std.c, кто-то упомянул бы, что стандарт не говорит о том, что в стеке появляются автоматические переменные, к счастью, SO не является comp.std.c!)
Обратите внимание, что я заставил переменные отображаться, потому что я передал их по ссылке - предположительно к функции, ожидающей указателя на постоянное целое число. Если адреса не были приняты, то j
и k
можно было бы полностью исключить из кода. Чтобы удалить i
, компилятор должен знать весь исходный код для всей программы - он доступен в других единицах перевода (исходные файлы) и поэтому не может быть легко удален. Совсем не так, если программа потакает динамической загрузке разделяемых библиотек - одна из этих библиотек может полагаться на эту глобальную переменную.
(Стилистически - переменные i
и j
должны иметь более длинные и более значимые имена, это только пример!)
Зависит от вашего компилятора, ваших системных возможностей, конфигурации при компиляции.
gcc
помещает константы только для чтения в раздел .text
, если не указано иное.
нет, потому что
1) сегмент bss хранит неинициализированные переменные, очевидно, что существует другой тип.
(I) large static and global and non constants and non initilaized variables it stored .BSS section.
(II) second thing small static and global variables and non constants and non initilaized variables stored in .SBSS section this included in .BSS segment.
2) сегмент данных - это инициализированные переменные, у которых есть 3 типа,
(I) large static and global and initlaized and non constants variables its stord in .DATA section.
(II) small static and global and non constant and initilaized variables its stord in .SDATA1 sectiion.
(III) small static and global and constant and initilaized OR non initilaized variables its stord in .SDATA2 sectiion.
я упоминаю выше, малые и большие средства откладываются на complier, например, малые средства < чем 8 байт и большие средствa > 8 байтов и равные значения.
но мое сомнение - это локальная константа, где он будет работать??????
Обычно они хранятся в разделе данных только для чтения (в то время как в разделе "Глобальные переменные" есть права на запись). Таким образом, попытка изменить константу, взяв ее адрес, может привести к нарушению доступа aka segfault.
Но это зависит от вашего оборудования, ОС и компилятора.
Это, в основном, обоснованное предположение, но я бы сказал, что константы обычно хранятся в фактических инструкциях процессора вашей скомпилированной программы, как немедленные данные. Другими словами, большинство инструкций включают в себя пространство для адреса для получения данных, но если это константа, пространство может удерживать само значение.
Глобальные и постоянные - это два полностью разделенных ключевых слова. У вас может быть один или другой, ни один, ни оба.
Если ваша переменная, хранящаяся в памяти, зависит от конфигурации. Немного прочитайте кучу и stack, это даст вам некоторые знания, чтобы задать больше (и, если возможно, более конкретные и более конкретные) вопросы.
Некоторые константы arfen't даже сохранены.
Рассмотрим следующий код: int x = foo(); x *= 2;
. Скорее всего, компилятор превратит умножение в x = x+x;
, поскольку это уменьшает необходимость загрузки номера 2 из памяти.
Он вообще не может быть сохранен.
Рассмотрим следующий код:
#import<math.h>//import PI
double toRadian(int degree){
return degree*PI*2/360.0;
}
Это позволяет программисту собирать представление о том, что происходит, но компилятор может оптимизировать некоторые из них, и большинство компиляторов делает это, оценивая постоянные выражения во время компиляции, а это значит, что значение PI может быть не в в результате программа вообще.
Как добавление, так как вы знаете, что его во время процесса связывания выделяется память из окончательного исполняемого файла. Существует еще один раздел COMMON, в котором размещаются общие символы из разных входных файлов. Это общее раздел фактически попадает под раздел .bss.
Он должен храниться в сегменте Text, так как он доступен только для чтения. http://shirleyanengineer.blogspot.in/2017/05/memory-layout-of-process.html
Я проверил в системе x86_64 GNU/Linux. Используя указатель на переменную 'const', значение можно изменить. Я использовал objdump. Не удалось найти переменную const в текстовом сегменте. Переменная const хранится в стеке.