3

Где хранятся временные объекты-константы? Знаю, что у констант, таких что не объявленных, то адреса нет, кроме строковых литералов, например:

printf("%d", 5); // Где хранится константа? В регистре процессора? Адреса у нее нет.
int value = 10; // Аналогично

printf("%s", "I am just a string"); // Адрес у строки есть, но где она хранится? На стеке?

Если можно, то простым языком) Спасибо!

Danny
  • 430
  • регистры процессора слишком мимолетны. да, константа в них конечно попадет в момент выполнения. А до этого она есть только в машинном коде инструкции, помещающей ее в регистр, например какого нибудь mov eax, 5 (если это x86) – Mike Jun 26 '20 at 20:38
  • А вот int value = 10; это не константа, а переменная, имеющая начальное значение 10. В зависимости от того что это за переменная, она может быть в сегменте данных программы, внутри исполнимого файла, может помещаться в стек в момент выполнения (опять же из машинного кода самой инструкции) или вообще использоваться непосредственно в инструкции где идет дальнейшая работа с ней – Mike Jun 26 '20 at 20:43
  • Что касается строки в printf - она будет в сегменте данных (который находиться отдельно внутри исполнимого файла) – Mike Jun 26 '20 at 20:45
  • 1
    https://ru.stackoverflow.com/q/618499/394322 – вася Jun 30 '20 at 05:48

1 Answers1

8

Стандарты C/C++ описывают только как ведут себя те или иные конструкции этих языков. Что происходит у программы "под капотом" в них не написано, поэтому зависит от компилятора. Сюда входит:

  • Что помещается в регистры (или куда-то еще), а что нет.
  • Существование стека и кучи. В стандарте написано только как долго существуют объекты, созданные тем или иным образом. Где они при этом находятся - не написано.
    (Хотя это занудство... На практике new создает объекты в куче, локальные переменные создаются в стеке, и т. д.)

Если хочется чего-то менее формального и более практичного, почитайте про сегменты объектных файлов.

Можете засунуть ваш код в дизассемблер (результат будет зависеть от выбора компилятора и флажков для него).

У меня получилось вот что:

  • Константы 5 и 10 стали частью инструкций mov ().
    mov esi, 5
    ...
    mov dword ptr [rbp - 4], 10
    
  • value - на стеке.
  • Про строковые литералы по выводу дизассемблера не очень понятно. Думаю правильно будет сказать, что они находятся "в сегменте данных" (см. ссылку про сегменты выше). Явно не в стеке - объекты на стеке уничтожаются при выходе из функции, а строковые литералы существуют все время работы программы.
HolyBlackCat
  • 27,445
  • 3
  • 27
  • 40
  • 1
    Что касается "взятия адреса константы" - то вы получаете адрес не константы, а ее копии - аргумента функции address, т.е. ее локальной переменной, находящейся в общем случае в стеке (и то необязательно; тут уж куда оптимизатор запихнет), и то только потому, что вы запросили ее адрес... – Harry Jun 27 '20 at 03:13
  • А можно ли считать 42 константой? Это ведь просто литерал, а само выражение имеет категорию категорию значения prvalue. – isnullxbh Jun 27 '20 at 03:14
  • @isnullxbh В C++ это литерал. В C это называется константой (слово литерал там вроде используется только для строковых литералов и для compound literals). – HolyBlackCat Jun 27 '20 at 08:35
  • @HolyBlackCat, понял, спасибо! – isnullxbh Jun 27 '20 at 08:37
  • @Harry Сначала хотел возвразить, потом вспомнил про temporary materialization и засомневался... Лучше вообще уберу эту часть ответа. – HolyBlackCat Jun 27 '20 at 08:54