2016-04-10 1 views
24

У меня есть переменная const в моей встроенной программе на C. Он определяется и инициализируется 0 в программном коде. Он помещается в специальную область ПЗУ через скрипт компоновщика. Можно изменить содержимое специальной области с помощью специальной процедуры программирования, но она не может быть изменена во время выполнения основной программы.Является ли компилятор C обязательным всегда перезагружать значение const из памяти?

Вопрос в том, должен ли я объявлять константу как volatile. Если он не помечен как volatile, то компилятору разрешено заменять все ссылки на него 0? Или он обязан загружать его хотя бы один раз во время выполнения программы?

+4

Почему вы говорите компилятору, что это const, когда это не так? –

+7

Сделайте это 'const volatile', это именно то, что для' volatile'. –

+9

@EdHeal 'const' не означает, что« это не изменится ». Это означает, что «это не изменится» через эту переменную * ». –

ответ

11

Если пометить как volatile, то компилятор обязан загрузить его из памяти каждый раз, когда ему это нужно.

Если не помечен как volatile, компилятор может нагрузки он когда-то из памяти, хранить его в регистр, и использовать этот регистр вместо загрузки его снова.

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

Оптимизация компиляторов может заметить const и решить, что она может быть скомпилирована с ее реальным, буквальным значением; до точки, где исходная константа не отображается вообще в разделе .data вашей программы. (Или, может быть, это так, но никогда не получается «читать».)

Поскольку вы изменяете значение в скрипте компоновщика, компилятор не может «знать» значение, полученное после компиляции. В этом случае используйте volatile: единственный способ сообщить компилятору не доверять тому, что значение известно при компиляции.

+0

«Оптимизация компиляторов может заметить const и решить, что она может быть скомпилирована с ее реальным, буквальным значением»; это совсем не **, что означает 'const'. –

+0

@Rhymoid: это случай 1 в http://stackoverflow.com/a/27466684/2564301 – usr2564301

+2

Без контекста, который предоставляет ответ, ваша фразировка вводит в заблуждение настолько, что люди считают, что 'const' означает больше, чем« компилятор будет жалуйтесь, если вы изменяете базовый объект через это значение lvalue ». Помните, что это один из самых сложных мифов о C, прямо там, где «C - это портативная сборка», «inline» означает, что компилятор определенно встроит функцию везде »и« sizeof (int) »CHAR_BIT = = 32'. –

28

Похоже, что ваша переменная действительно является константой (то есть не изменяется во время выполнения программы) со значением, неизвестным компилятору. Если это так, то вы можете объявить его как это:

extern const int variable; 

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

Компилятору будет разрешено загрузить его и, возможно, оставить его в регистре навсегда, но не заменить его на 0 или любое другое значение во время компиляции.

+0

Это хорошая рекомендация, однако я связан с решением с константой, определенной в коде, и помещается в ROM-корреляция через скрипты компоновщика. И вот мой вопрос - мне нужно использовать летучие или нет? – mrn

+2

Если вам действительно нужно определить переменную в C, тогда создайте отдельный исходный файл, содержащий ничего, кроме 'const int variable = 0;', скомпилируйте его отдельно от всего вашего другого кода и свяжите его. –

+5

«Я обязан решение «Я не уверен, почему именно это называется« решением », а не как« проблема ». но что бы это ни было, если нет других проблем, вы должны использовать 'volatile' –

Смежные вопросы