Если мы объявляем переменную как volatile
каждый раз, когда обновляется новое значение.
Если мы объявляем переменную как, const
то значение этой переменной не будет изменено.
Тогда в const volatile int temp;
чем смысл объявления переменной, temp
как указано выше?
Что произойдет, если мы объявим как const int temp
?
const volatile int temp;
в области видимости блока (т.е. внутри{ }
), там это бесполезно.Ответы:
Объект, помеченный как
const volatile
, не может быть изменен кодом (из-заconst
квалификатора будет вызвана ошибка ) - по крайней мере, через это конкретное имя / указатель.volatile
Часть Классификатора означает , что компилятор не может оптимизировать или изменить порядок доступа к объекту.Во встроенной системе это обычно используется для доступа к аппаратным регистрам, которые могут быть прочитаны и обновлены оборудованием, но не имеет смысла для записи (или может быть ошибкой при записи).
Примером может служить регистр состояния последовательного порта. Различные биты будут указывать, ожидает ли символ чтения или готов ли регистр передачи принять новый символ (т. Е. - он пуст). Каждое чтение этого регистра состояния может приводить к другому значению в зависимости от того, что еще произошло в оборудовании последовательного порта.
Нет смысла писать в регистр состояния (в зависимости от конкретной спецификации оборудования), но вам необходимо убедиться, что каждое чтение регистра приводит к фактическому чтению оборудования - с использованием кэшированного значения из предыдущего выигранного чтения ' Расскажу об изменениях в состоянии оборудования.
Быстрый пример:
unsigned int const volatile *status_reg; // assume these are assigned to point to the unsigned char const volatile *recv_reg; // correct hardware addresses #define UART_CHAR_READY 0x00000001 int get_next_char() { while ((*status_reg & UART_CHAR_READY) == 0) { // do nothing but spin } return *recv_reg; }
Если эти указатели не были помечены как существующие
volatile
, может возникнуть пара проблем:*recv_reg
, что цикл изменен, нет причин, по которым его нельзя прочитать перед входом в цикл.В
volatile
классификаторы гарантирует , что эти оптимизации не выполняются компилятором.источник
volatile
сообщит компилятору не оптимизировать код, связанный с переменной, обычно, когда мы знаем, что она может быть изменена «извне», например, другим потоком.const
сообщит компилятору, что программе запрещено изменять значение переменной.const volatile
это очень особенная вещь, которую вы, вероятно, увидите, использованную ровно 0 раз в вашей жизни (тм). Как и следовало ожидать, это означает, что программа не может изменять значение переменной, но значение может быть изменено извне, поэтому никакая оптимизация не будет выполняться для переменной.источник
volatile
переменные обычно происходят, когда вы начинаете возиться с оборудованием, а не с другими потоками. Я видел, чтоconst volatile
используется в таких вещах, как регистры состояния с отображением в память или тому подобное.Это не из-за того, что переменная константа, она не могла измениться между двумя точками последовательности.
Константа - это обещание, которое вы даете не изменять значение, а не то, что значение не будет изменено.
источник
const
данные не «постоянны».Мне нужно было использовать это во встроенном приложении, где некоторые переменные конфигурации расположены в области флэш-памяти, которую можно обновить с помощью загрузчика. Эти переменные конфигурации являются "постоянными" во время выполнения, но без квалификатора volatile компилятор оптимизирует что-то вроде этого ...
cantx.id = 0x10<<24 | CANID<<12 | 0;
... путем предварительного вычисления значения константы и использования инструкции немедленной сборки или загрузки константы из ближайшего местоположения, так что любые обновления исходного значения CANID в области конфигурации flash будут игнорироваться. CANID должен быть постоянно изменчивым.
источник
В C const и volatile являются квалификаторами типа, и они независимы.
По сути, const означает, что значение не может быть изменено программой.
А volatile означает, что значение может внезапно измениться (возможно, извне программы).
Фактически, стандарт C упоминает пример действительного объявления, которое одновременно является константным и изменчивым. Пример такой
«Extern const volatile int real_time_clock;»
где real_time_clock может быть изменен аппаратно, но не может быть назначен, увеличен или уменьшен.
Таким образом, мы уже должны рассматривать const и volatile отдельно. Кроме того, этот квалификатор типа также применяется к struct, union, enum и typedef.
источник
Вы можете использовать const и volatile вместе. Например, если предполагается, что 0x30 является значением порта, который изменяется только внешними условиями, следующее объявление предотвратит любую возможность случайных побочных эффектов:
const volatile char *port = (const volatile char *)0x30;
источник
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
объявлено ISvoltaile
, изменение идентификатора вступит в силу немедленно.источник
В этой статье обсуждаются сценарии, в которых вы хотите комбинировать квалификаторы const и volatile.
http://embeddedgurus.com/barr-code/2012/01/combining-cs-volatile-and-const-keywords/
источник
Проще говоря, значение в переменной 'const volatile' не может быть изменено программно, но может быть изменено аппаратно. Неустойчивый здесь предназначен для предотвращения любой оптимизации компилятора.
источник
Мы используем ключевое слово const для переменной, когда не хотим, чтобы программа изменяла ее. В то время как, когда мы объявляем переменную const volatile, мы говорим программе не изменять ее, а компилятору, что эта переменная может быть изменена неожиданно из-за ввода из внешнего мира.
источник