Const vs Static Const

Как компилятор (например, GCC) выделяет переменную const и static const, например, где она будет находиться? В памяти данных или в памяти программы?

Ответ 1

Это зависит от вашей системы и от того, как вы используете переменную. Для переменных static:

Случай 1:. Вы никогда не используете переменную, и компилятор молча отбрасывает ее. Это не может произойти с переменными extern.

Случай 2:. Вы используете переменную, но вы никогда не берете ее адрес. Компилятор преобразует использование переменной в непосредственные операнды, как если бы это был #define или enum. Компилятор все равно может преобразовать статический текст extern в непосредственные операнды, но он все равно должен найти для него адрес.

Случай 3:. Вы используете переменную и берете ее адрес, компилятор вынужден найти место, чтобы поместить его в код объекта, точно так же, как если бы он был extern.

Что касается "данных" и "программной" памяти, это очень специфично для используемой вами системы. В моей Linux x64/ELF системе он, вероятно, попадет в раздел .rodata, который идет в том же сегменте, что и код (.text), но другой сегмент из разделов данных чтения и записи (.bss, .data). Моя система, похоже, не создает отдельный сегмент для не исполняемых данных только для чтения.

Добавление: Обратите внимание, что поведение отличается от С++. В С++ переменная const имеет внутреннюю привязку по умолчанию, поэтому static const является избыточным, а extern const необходим для получения константы с внешней связью.

Ответ 2

Дитрих уже хорошо объяснил случай static переменных.

Для локальных переменных реализация компилятора имеет несколько вариантов, на которых выделяется const квалифицированная переменная, для которой выполняется адрес. Он может или не может быть выделен в стеке или в статической памяти. Это особенно характерно для const квалифицированных составных литералов. Адреса двух таких литералов, локально объявленных в разных областях, могут быть свернуты в один, и их адреса могут сравниться равными.