Где хранятся статические константы?

Если константа определена глобально, она переходит в сегмент text. Локальные константы помещаются в stack. Статические переменные сохраняются в сегменте data или bss в зависимости от того, инициализирован ли он на месте и чем он инициализирован.

А что насчет static const? Этот вопрос связан с другим вопросом, который только о статических переменных, а не о константах. Я полагаю, что статические константы должны храниться в сегменте text как переменные только для чтения, но я не уверен. Где это обычно хранится?


person Kaiyakha    schedule 06.12.2020    source источник
comment
Что говорит файл карты?   -  person Martin James    schedule 06.12.2020
comment
@MartinJames У меня есть исполняемый файл только после компиляции   -  person Kaiyakha    schedule 06.12.2020
comment
Скажите компоновщику, чтобы он написал полный файл карты ...   -  person Martin James    schedule 06.12.2020
comment
@MartinJames, какие варианты для этого есть в gcc или clang?   -  person Kaiyakha    schedule 06.12.2020
comment
Извините .... вы просите меня найти для вас команды компоновщика?   -  person Martin James    schedule 06.12.2020
comment
@MartinJames, конечно, я думал, что ты знаешь, как это сделать, если ты это предложил. Кроме того, я компилирую только через командную строку   -  person Kaiyakha    schedule 06.12.2020
comment
Погуглите директивы командной строки компоновщика.   -  person Martin James    schedule 06.12.2020


Ответы (1)


static const может быть свернут во время компиляции. В противном случае он сохраняется в сегменте data или bss, как если бы он был static (но другие модули не могут связываться с ним). Хранение его в сегменте text допустимо, но очень немногие компиляторы делают это. Я видел это только во встроенных компиляторах, где различие между RAM и ROM имеет значение. В новых наборах инструментов часто есть rodata сегмент, который принимает статические и глобальные константы.

person Joshua    schedule 06.12.2020
comment
Ну, мой компилятор clang хранит его рядом с константами, как если бы он был в разделе text. gcc делает то же самое, но этот, похоже, не соответствует стандартной схеме памяти (почему-то константы имеют более высокие адреса, чем инициализированные глобальные переменные) - person Kaiyakha; 06.12.2020
comment
@Kaiyakha: Более высокий адрес указывает мне, что он использует rodata. - person Joshua; 06.12.2020
comment
@ оно выше, чем data? - person Kaiyakha; 06.12.2020
comment
@Kaiyakha: Зависит от порядка ссылок, но может быть. - person Joshua; 06.12.2020
comment
А что насчет clang? Адреса static const (локальные и глобальные) находятся рядом с адресами строковых литералов и других глобальных констант, и все адреса намного меньше, чем адреса переменных из сегмента data (глобальные переменные инициализируются на месте ненулевыми значениями) - person Kaiyakha; 06.12.2020
comment
@Kaiyakha: Я не использую clang. - person Joshua; 06.12.2020
comment
Хорошо, что ты имеешь в виду под folded? - person Kaiyakha; 06.12.2020
comment
@Kaiyakha: компилятору разрешено помещать значение статической константы везде, где она используется, и исключать переменную. - person Joshua; 06.12.2020
comment
Наконец, я думаю, что static const находится рядом с другими константами как для clang, так и для gcc. Для clang более вероятно, что он находится в сегменте text, потому что его адрес является наименьшим среди других констант, а для gcc он, вероятно, находится в том, что вы называете rodata. Во всяком случае, это всегда помимо других констант для обоих компиляторов. - person Kaiyakha; 06.12.2020
comment
Основываясь на том, где, как вы думаете, что-то размещается на основе адреса, немного глупо, взгляните на дамп объекта и устраните сомнения. (objdump на платформах * nix или dumpbin.exe при использовании MSVC). Хотя взятие адреса само по себе может вызвать создание объекта, который в противном случае не понадобился бы. - person SoronelHaetir; 06.12.2020
comment
@SoronelHaetir в том-то и дело, у меня нет ни * nix, ни MSVC. Я компилирую через командную строку в Windows - person Kaiyakha; 06.12.2020
comment
Ваш набор инструментов создает двоичный файл в формате some, очень вероятно, что существует инструмент, который сбрасывает результирующий объектный файл, даже если это не собственный формат для платформы. Например, в моих установках clang с кросс-компиляцией есть llvm-objdump. - person SoronelHaetir; 07.12.2020