Память, выделенная во время компиляции, означает, что компилятор разрешает во время компиляции, где определенные вещи будут выделяться внутри карты памяти процесса.
Например, рассмотрим глобальный массив:
int array[100];
Компилятор знает во время компиляции размер массива и размер int
, поэтому он знает весь размер массива во время компиляции. Также глобальная переменная имеет статическую длительность хранения по умолчанию: она размещается в области статической памяти пространства памяти процесса (раздел .data / .bss). Учитывая эту информацию, компилятор решает во время компиляции, по какому адресу этой статической области памяти будет массив .
Конечно, адреса памяти - это виртуальные адреса. Программа предполагает, что она имеет собственное пространство памяти (например, от 0x00000000 до 0xFFFFFFFF). Вот почему компилятор может делать предположения типа «Хорошо, массив будет по адресу 0x00A33211». Во время выполнения эти адреса преобразуются в реальные / аппаратные адреса MMU и ОС.
Значение инициализированного статического хранилища вещей немного отличается. Например:
int array[] = { 1 , 2 , 3 , 4 };
В нашем первом примере компилятор только решил, где будет размещен массив, сохранив эту информацию в исполняемом файле.
В случае вещей, инициализированных значением, компилятор также вводит начальное значение массива в исполняемый файл и добавляет код, который сообщает загрузчику программы, что после выделения массива при запуске программы массив должен быть заполнен этими значениями.
Вот два примера сборки, сгенерированной компилятором (GCC4.8.1 с целью x86):
C ++ код:
int a[4];
int b[] = { 1 , 2 , 3 , 4 };
int main()
{}
Выходная сборка:
a:
.zero 16
b:
.long 1
.long 2
.long 3
.long 4
main:
pushq %rbp
movq %rsp, %rbp
movl $0, %eax
popq %rbp
ret
Как видите, значения непосредственно вводятся в сборку. В массиве a
компилятор генерирует нулевую инициализацию 16 байтов, потому что стандарт говорит, что статические хранимые вещи должны быть по умолчанию инициализированы нулем:
8.5.9 (Инициализаторы) [Примечание]:
Каждый объект статической длительности хранения инициализируется нулями при запуске программы перед любой другой инициализацией. В некоторых случаях дополнительная инициализация выполняется позже.
Я всегда предлагаю людям разобрать свой код, чтобы посмотреть, что на самом деле делает компилятор с кодом C ++. Это относится от классов хранения / продолжительности (как этот вопрос) к расширенной оптимизации компилятора. Вы могли бы поручить вашему компилятору сгенерировать сборку, но есть замечательные инструменты, чтобы сделать это в Интернете дружественным образом. Мой любимый это GCC Explorer .