const
означает, что переменная не может быть изменена кодом c, а не то, что она не может быть изменена. Это означает, что никакая инструкция не может записывать в переменную, но ее значение может измениться.
volatile
означает, что переменная может измениться в любое время, и поэтому кэшированные значения не могут использоваться; каждый доступ к переменной должен выполняться по ее адресу памяти.
Поскольку вопрос помечен как «встроенный» и предположим, что temp
это переменная, объявленная пользователем, а не регистр, связанный с оборудованием (поскольку они обычно обрабатываются в отдельном файле .h), примите во внимание:
Встроенный процессор, который имеет как энергозависимую память для чтения-записи данных (RAM), так и энергонезависимую постоянную память данных, например FLASH-память в архитектуре фон-Неймана, где данные и пространство программы совместно используют общую шину данных и адреса.
Если вы объявляете, const temp
что у вас есть значение (по крайней мере, если оно отличается от 0), компилятор присвоит переменной адрес во флэш-пространстве, потому что даже если он был назначен на адрес ОЗУ, ему все равно нужна флэш-память для хранения начального значения. переменной, что делает адрес ОЗУ пустой тратой места, поскольку все операции доступны только для чтения.
В результате:
int temp;
- это переменная, хранящаяся в ОЗУ, инициализируемая значением 0 при запуске (cstart), могут использоваться кэшированные значения.
const int temp;
- это переменная, хранящаяся в (только для чтения) FLASH, инициализируемая значением 0 во время компиляции, могут использоваться кэшированные значения.
volatile int temp;
- это переменная, хранящаяся в ОЗУ, инициализируемая значением 0 при запуске (cstart), кэшированные значения НЕ будут использоваться.
const volatile int temp;
- это переменная, хранящаяся в (только для чтения) FLASH, инициализированная 0 во время компиляции, кешированные значения НЕ будут использоваться
А вот и полезная часть:
В настоящее время большинство встроенных процессоров имеют возможность вносить изменения в свою энергонезависимую память только для чтения с помощью специального функционального модуля, который const int temp
может быть изменен во время выполнения, а не напрямую. Иными словами, функция может изменять значение по адресу, где temp
оно хранится.
Практическим примером может быть использование temp
серийного номера устройства. При первом temp
запуске встроенного процессора он будет равен 0 (или объявленному значению), и функция может использовать этот факт для запуска теста во время производства, и в случае успешного выполнения запросить присвоение серийного номера и изменить значение temp
с помощью специальной функции. У некоторых процессоров есть специальный диапазон адресов с одноразовой программируемой памятью.
Но вот разница:
Если const int temp
это изменяемый идентификатор вместо одноразового программируемого серийного номера и НЕ объявлен volatile
, кешированное значение может использоваться до следующей загрузки, то есть новый идентификатор может быть недействительным до следующей перезагрузки или, что еще хуже, некоторых функций может использовать новое значение, в то время как другие могут использовать более старое кешированное значение до перезагрузки. Если const int temp
объявлено IS voltaile
, изменение идентификатора вступит в силу немедленно.
const volatile int temp;
в области видимости блока (т.е. внутри{ }
), там это бесполезно.