Как компиляция резервирует место в стеке?

Я не очень хорошо разбираюсь в компьютерах, поэтому мои вопросы довольно наивны.

Я узнал, что компиляция кода C резервирует определенное пространство памяти в стеке в основной памяти во время компиляции.

Затем,

  1. Почему исполняемый файл работает, если он скомпилирован на одном компьютере и скопирован на другой компьютер?

  2. Если компиляция резервирует определенное место в памяти ОЗУ, то ограничивается ли количество исполняемых файлов (или компиляции) размером ОЗУ?

  3. Если компиляция резервирует место в оперативной памяти, почему исполняемый файл занимает намного больше места на диске, чем текстовый файл .C перед компиляцией?

Спасибо

Краткий ответ: Однако хочет. Стандарт C не заставляет вас что-либо делать и даже не имеет стека. На практике некоторые операционные системы имеют настройки по умолчанию при запуске исполняемых файлов на любом языке. Если вы хотите узнать больше, вот пример о Rust, который объясняет, что происходит до запуска вашей main() функции. На самом деле в вашем исполняемом файле много чего происходит.

tadman 25.01.2023 17:43

Компиляция не резервирует место во время компиляции. Он генерирует код, который делает это при загрузке программы. Программу можно загрузить на другой компьютер.

Barmar 25.01.2023 17:45

На любой из ваших вопросов нет простого ответа в один абзац. Если вы действительно хотите в этом разобраться, пройдите курс NAND to Tetris.

Corvus 25.01.2023 17:46

Это существенное различие между компиляторами и интерпретаторами. Компиляторы генерируют код, который можно выполнить позже, потенциально на другом компьютере. Интерпретаторы немедленно выполняют код.

Barmar 25.01.2023 17:50

После компиляции исполняемый код вашей программы и некоторые данные, которые могут быть известны во время компиляции. Этот код и фиксированные данные (исполняемый файл может быть довольно большим, если таких данных много) загружаются в память (код может быть загружен в память, защищенную от записи). Затем операционная ищет информацию о том, по какому адресу находится первая инструкция программы, и запускается оттуда. Затем, когда выполняются вызовы, локальные переменные функции (есть на большинстве компьютеров) помещаются в стек.

Pepijn Kramer 25.01.2023 18:00

@Barnar Не совсем, если у вас есть статические переменные, они занимают место в вашем исполняемом файле (попробуйте большой статический массив, если хотите убедиться в этом сами)

Pepijn Kramer 25.01.2023 18:01

@PepijnKramer Таким образом, он резервирует место на диске, а не в оперативной памяти. Оперативная память становится зарезервированной после загрузки исполняемого файла

Eugene Sh. 25.01.2023 18:03

Читайте внимательно, не ВСЯ память, необходимая программе, зарезервирована на диске. только память, необходимая статическим переменным. Локальные переменные (в большинстве систем) попадают в стек, а динамически выделенная память (new/delete/std::make_unique) оказывается где-то в оперативной памяти (обычно называемой кучей).

Pepijn Kramer 25.01.2023 18:12
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
115
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
  1. Стек не резервируется компилятором во время компиляции. Он зарезервирован в том смысле, что компилятор вставляет определенные команды и директивы в исполняемый файл, чтобы стек был зарезервирован при загрузке/запуске исполняемого файла.

  2. См. выше. Оперативная память не резервируется (то есть становится недоступной для других исполняемых файлов) во время компиляции. Он зарезервирован, когда исполняемый файл загружается/выполняется.

  3. Это не обязательно правда. Во многих случаях исполняемый файл меньше кода. Но это может зависеть от многих факторов, таких как способ написания кода, формат исполняемого файла, включенные в него метаданные и расположение памяти. Иногда исполняемый файл будет содержать целые разделы, заполненные нулями, которые могут быть определены одной строкой кода.

В общем, у компилятора (в сочетании с компоновщиком, если мы хотим быть педантичными) есть только одна «простая» задача — взять входные файлы (код) и сгенерировать выходной файл (ы) — исполняемый файл. То есть - это создание файлов, которые только занимают место в файловой системе. Другие вещи могут происходить только тогда, когда среда (ОС) загружается и что-то с ними делает (загружает, выполняет).

Вопрос № 2 также вызван незнанием виртуальной памяти.

Mooing Duck 25.01.2023 18:01

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

NathanOliver 25.01.2023 18:14

@NathanOliver Мне довелось увидеть исходный код, который вообще не читался человеком :)

Eugene Sh. 25.01.2023 18:15

Пространство не резервируется во время компиляции. Во время компиляции генерируются инструкции, которые при выполнении во время выполнения занимают место в стеке.

Например, когда вы объявляете переменную в своем коде:

int x = 5;

Компилятор выдаст инструкции, которые помещают в стек 4 байта (допустим, это размер int). Но это происходит во время выполнения. Это пространство резервируется при достижении этой строки кода во время выполнения. Предупреждение здесь заключается в том, что оптимизирующий компилятор может делать здесь все, что угодно, и может фактически не выделять пространство стека.

Это работает, когда вы копируете исполняемый файл на другую машину, потому что резервирование стека будет происходить на этой машине во время выполнения кода.

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

Другие вопросы по теме