The difference between const and const volatile

If we declare a variable as volatile every time a new value is updated
If we declare the variable as const , then the value of this variable will not be changed

Then const volatile int temp;
What is the use of the temp variable declaration as above?
What happens if we declare as const int temp ?

+61
c embedded
Jan 04 2018-11-11T00:
source share
9 answers

An object marked as const volatile will not be allowed to change the code (an error will be caused due to the const qualifier) ​​- at least through this specific name / pointer.

Part of the volatile qualifier means that the compiler cannot optimize or reorder access to the object.

In an embedded system, this is usually used to access hardware registers that can be read and updated by the hardware, but do not make sense to write (or may be a write error).

An example would be the status register for a serial port. Different bits will indicate whether the character is waiting to be read or if the transmit register is ready to accept a new character (i.e., it is empty). Each reading of this status register may lead to a different value depending on what else happened on the serial port device.

It makes no sense to write to the status register (depending on the specific hardware specification), but you need to make sure that each reading of the register leads to the actual reading of the hardware - using the cached value from the previous read will not tell you about changes in the state of the equipment.

Quick example:

 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; } 

If these pointers were not marked as volatile , two problems can occur:

  • the while loop test can read the status register only once, since the compiler could assume that everything that it pointed out would never change (nothing can be changed in the while loop test or in the loop). If you entered a function when there was no character in the UART, you may end up in an endless loop that never stopped even when a character was received.
  • reading the receive register can be moved by the compiler to the while loop - again, because there is nothing in the function that indicates *recv_reg changing in the loop, there is no reason why it cannot be read before entering the loop.

The volatile qualifiers ensure that these optimizations are not performed by the compiler.

+93
Jan 04 '11 at 18:44
source share
  • volatile will tell the compiler that it should not optimize the code associated with the variable, usually when we know that it can be changed from "outside", for example. another thread.
  • const will tell the compiler that the program is forbidden to change the value of a variable.
  • const volatile is a special thing that you are likely to see being used exactly 0 times in your life (tm). As expected, this means that the program cannot change the value of the variable, but the value can be changed externally, so optimization will not be performed for the variable.
+22
Jan 04 2018-11-11T00:
source share

This is not because the variable is const, that it cannot be changed between two points in a sequence.

A constant is a promise that you do not change the value, and not that the value will not be changed.

+20
Jan 04 2018-11-11T00:
source share

I need to use this in an embedded application, where some configuration variables are located in a flash area that can be updated by the bootloader. These configuration variables are "persistent" at runtime, but without a volatile qualifier, the compiler optimizes something like this ...

 cantx.id = 0x10<<24 | CANID<<12 | 0; 

... by pre-calculating the constant value and using the direct build command or loading the constant from the nearest location, so that any updates to the original CANID value in the configuration area will be ignored. CANID must be const volatile.

+5
Jun 28 '15 at 10:55
source share

In C, const and volatile are type classifiers, and the two are independent.

Basically, const means that the value is not modified by the program.

And volatile means that the value is subject to a sudden change (possibly outside the program).

In fact, the C standard mentions an example of a valid declaration, which is both const and volatile. Example:

"extern const volatile int real_time_clock;"

where real_time_clock can be changed using hardware, but cannot be assigned to increase or decrease.

So, we should already consider const and volatile separately. In addition, this type of classifier is used for struct, union, enum and typedef.

+3
Aug 09 '16 at 11:19
source share

const means that the variable cannot be changed by c, but cannot be changed. This means that no command can write a variable, but its value can still change.

volatile means that a variable can change at any time, and thus cached values ​​cannot be used; every access to the variable must be done at the memory address.

Since the question is marked as β€œinline”, and suppose temp is a user-declared variable and not hardware-related (since they are usually processed in a separate .h file), consider:

An integrated processor that has both volatile data memory for reading and writing, and non-volatile data memory for reading only, for example, FLASH memory in the von Neumann architecture, where the data and program space share a common data and address bus.

If you declare a const temp value (at least if it is different from 0), the compiler will assign a variable to an address in the FLASH space, because even if it was assigned to a RAM address, it still needs FLASH memory to save the initial value of the variable. making the RAM address a waste of space, since all operations are read-only.

As a result:

int temp; - this is a variable stored in RAM, initialized to 0 at startup (cstart), cached values ​​can be used.

const int temp; is a variable stored in (read-ony) FLASH, initialized to 0 at compiler time, cached values ​​can be used.

volatile int temp; - this is a variable stored in RAM, initialized to 0 at startup (cstart), cached values ​​will NOT be used.

const volatile int temp; is a variable stored in (read-ony) FLASH, initialized to 0 at compiler time, cached values ​​will NOT be used

Here is the helpful part:

Currently, most embedded processors have the ability to make changes to their non-volatile read-only memory using a special function module, in which case const int temp can be changed at run time, and not directly. On the other hand, a function can change the value at the address where temp is stored.

A practical example would be to use temp for the serial number of a device. At the first start of the built-in processor, temp will be 0 (or the declared value), and the function can use this fact to run the test during production and, if necessary, ask to assign a serial number and change the value from temp using a special function. Some processors have a special address range with OTP (one-time programmable) memory.

But here comes the difference:

If const int temp is a mutable identifier instead of a one-time programmable serial number and Volatile is NOT declared, the cached value can be used until the next boot, that is, the new identifier may be invalid until the next reboot or, even worse, some functions may use the new value, while others may use the older cached value before reloading. If const int temp declared voltaile , the change of identifier takes effect immediately.

+2
Sep 30 '15 at 16:38
source share

This article discusses scenarios in which you want to combine constant and unstable qualifiers.

http://embeddedgurus.com/barr-code/2012/01/combining-cs-volatile-and-const-keywords/

+2
Nov 15 '15 at 7:55
source share

You can use const and volatile together. For example, if 0x30 is considered a port value that changes only by external conditions, the following expression would prevent any possibility of accidental side effects:

 const volatile char *port = (const volatile char *)0x30; 
+2
Dec 23 '16 at 17:08
source share

We use the keyword 'const' for a variable if we do not want the program to change it. If we declare a 'const volatile' variable, we tell the program not to change it and the compiler that this variable may unexpectedly change from input coming from the outside world.

+1
Nov 17 '15 at 3:30
source share



All Articles