const
означає, що змінна не може бути змінена кодом c, не те, що вона не може змінюватися. Це означає, що жодна інструкція не може писати у змінну, але її значення все одно може змінитися.
volatile
означає, що змінна може змінюватися в будь-який час і, отже, не можна використовувати кешовані значення; кожен доступ до змінної повинен виконуватися за адресою пам'яті.
Оскільки питання позначено тегом "вбудовано" і припустимо temp
, що це змінна, оголошена користувачем, а не апаратно-пов'язаний регістр (оскільки вони зазвичай обробляються в окремому файлі .h), розглянемо:
Вбудований процесор, який має як енергонезалежну пам'ять даних для читання-запису (ОЗУ), так і енергонезалежну пам'ять, доступну лише для читання, наприклад FLASH-пам'ять у архітектурі фон-Неймана, де дані та простір програм мають спільну шину даних та адреси.
Якщо ви заявите, const temp
що має значення (принаймні, якщо воно відрізняється від 0), компілятор призначить змінну адресі в просторі FLASH, оскільки навіть якщо вона була призначена адресі оперативної пам'яті, вона все одно потребує пам'яті FLASH для зберігання початкового значення змінної, роблячи адресу оперативної пам'яті марною тратою місця, оскільки всі операції доступні лише для читання.
Як наслідок:
int temp;
- змінна, що зберігається в оперативній пам'яті, ініціалізована до 0 при запуску (cstart), можуть використовуватися кешовані значення.
const int temp;
- це змінна, що зберігається у (read-ony) FLASH, ініціалізована до 0 під час компілятора, можуть використовуватися кешовані значення.
volatile int temp;
- це змінна, яка зберігається в оперативній пам'яті, ініціалізована до 0 при запуску (cstart), кешовані значення НЕ будуть використовуватися.
const volatile int temp;
- це змінна, що зберігається у (read-ony) FLASH, ініціалізована до 0 під час компілятора, кешовані значення НЕ будуть використовуватися
Ось корисна частина:
На сьогоднішній день більшість вбудованих процесорів мають можливість вносити зміни до своєї енергонезалежної пам'яті, доступної лише для читання, за допомогою спеціального функціонального модуля, в цьому випадку const int temp
його можна змінити під час виконання, не безпосередньо. Зазначене іншим чином, функція може модифікувати значення за адресою, де temp
зберігається.
Практичним прикладом може бути використання temp
серійного номера пристрою. Під час першого запуску вбудованого процесора temp
буде дорівнює 0 (або заявленому значенню), і функція може використовувати цей факт для запуску тесту під час виробництва, і якщо це вдало, попросіть присвоїти серійний номер і змінити значення temp
за допомогою особливої функції. Деякі процесори мають спеціальний діапазон адрес з OTP (одноразово програмованою) пам'яттю саме для цього.
Але тут різниця:
Якщо const int temp
модифікуваний ідентифікатор замість одноразово програмованого серійного номера і НЕ оголошений volatile
, кешоване значення може бути використано до наступного завантаження, тобто новий ідентифікатор може бути недійсним до наступного перезавантаження або, що ще гірше, деяких функцій може використовувати нове значення, тоді як інше може використовувати старіше кешоване значення до перезавантаження. Якщо const int temp
IS оголошено voltaile
, зміна посвідчення набере чинності негайно.
const volatile int temp;
в області блоку (тобто всередині{ }
), він там не має ніякої користі.