структуры данных, выделенные во время компиляции? - PullRequest
2 голосов
/ 27 апреля 2020

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

  1. Если у меня есть некоторые переменные и массивы (размер которых известен во время компиляции), внутри функции она все еще выделяется, если функция не называется вообще?

  2. Как это связано с размером файла. c и исполняемого файла .out?

  3. Где я могу найти такие вещи, как эти? Вы знаете, некоторые хорошие книги по программированию, которые не только преподают язык, но и основополагающие принципы работы в памяти.

Ответы [ 2 ]

4 голосов
/ 27 апреля 2020
  1. Если у меня есть некоторые переменные и массивы (размер которых известен во время компиляции), внутри функции будет ли она по-прежнему выделяться, если функция вообще не вызывается?

Что говорит спец c

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

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

Что вы можете увидеть на практике

C реализациям разрешено во многих отношениях отклоняться от деталей спецификации, если они производят такое же наблюдаемое поведение, как если бы они следовали инструкции c к букве , Среди отклонений, которые вы можете увидеть, есть

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

  • Если компилятор определит, что данная переменная не может быть прочитана, тогда переменная и любые записи в нее могут быть вообще опущены (если это не volatile).

  • В принципе, программа не может распределять или инициализировать переменные состояния c до тех пор, пока к ним не будет получен первый доступ (хотя это маловероятно).

  • Хвостовые рекурсивные вызовы функций могут быть свернуты в итерации, так что локальные переменные функции используются повторно, а не новые создаются для каждого рекурсивного вызова.

Какое отношение это имеет к размеру файла. c и исполняемого файла .out?

Исходный файл. c состоит из кода, который вы пишете , Если вы напишите больше кода, то он будет больше. Если вы пишете меньше кода, то он становится меньше.

Возможно, вы имели в виду объектные файлы (.o по Unix соглашению). Spe c не говорит здесь о вопросе, и даже не говорит напрямую с такими файлами вообще. На практике реализации различаются, но обычно из всех локальных переменных, сохраняемых компилятором, только те, которые static и объявлены с ненулевыми инициализаторами, занимают место в объектных файлах, двоичных библиотеках или исполняемых файлах.

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

Извините, но эта часть вопроса вне обсуждения c для переполнения стека. Мы не отвечаем на вопросы, требуя рекомендаций для сторонних материалов, включая, помимо прочего, учебники и учебные пособия.

0 голосов
/ 27 апреля 2020

Если вы объявили свои переменные с размером, что-то вроде

int a[10];

Это означает, что память будет использоваться из стека. Это выделяется во время компиляции (stati c).

Обычно, если вы не вызываете функцию, препроцессор компилятора удаляет этот код. Таким образом, вы можете не заметить разницу в использовании памяти просто потому, что ваш компилятор был умным.

. C и файлы .OUT - это просто файлы с командами, на которые не влияют объявления памяти. Но если в вашем коде есть что-то вроде макроса, это может увеличить размер после компиляции. можете прочитать о диспетчере памяти, динамической c и статической c памяти (куча и стек), чтобы получить хорошее представление

...