Pointer declared as constant as well as volatile

CConstantsVolatile

C Problem Overview


While reading I came across this type of declaration and the following line -

const volatile char *p=(const volatile char *) 0x30;

>The value of p is changed by external conditions only

I don't get what are the external conditions . And also what is practical use of this type of declaration?

C Solutions


Solution 1 - C

The const says that the flow of your program isn't going to modify what is pointed to by p. Any attempt to modify the value after dereferencing the pointer will result in a compile-time error:

*p = 'A'; // will not compile

Note that this isn't a particularly strong contract; the value at location 0x30 can still be changed through an aliasing non-const pointer, other than p:

volatile char *q = 0x30;
*q = 'A'; // will compile

Another way to break this contract is by casting away the const from p:

*(volatile char *) p = 'A'; // will compile

The volatile, however, doesn't exclude any modifications which could be caused by another thread, the kernel, an asynchronous signal handler or an external device which has access to the same memory space. This way the compiler cannot make the wrong assumption that the value pointed to by p doesn't change and will load it from memory every time it is referenced:

/*
 The character at 0x30 will be read on every iteration,
 even if the compiler has proven that the program itself
 doesn't modify the value at that address.
*/
while (*p) {
    ...
}

If the compiler was to erroneously optimise such a construct, it could emit instructions which load the value only once from memory and then keep it in a register. The register is essentially an independent copy and any changes to the original location will not reflect there, and, needless to say, this can cause some very nasty bugs.

Solution 2 - C

Consider a read-only hardware register, of your network card for example.

It might change outside the control of the program, so the compiler is not allowed to cache its value in a register or optimize it away. Thus, volatile.

And it's read-only, so you shouldn't write to it. Thus, const.

Solution 3 - C

First, let me quote the example from C11 standard, chapter §6.7.3, Type qualifiers

> An object declared > > extern const volatile int real_time_clock; > > may be modifiable by hardware, but cannot be assigned to, incremented, or decremented.

Also, related footnote (134),

> A volatile declaration may be used to describe an object corresponding to a memory-mapped input/output port or an object accessed by an asynchronously interrupting function. Actions on objects so declared shall not be "optimized out" by an implementation or reordered except as permitted by the rules for evaluating expressions.

That means, the value of the variable can be modified by the hardware (through the memory-mapping), but cannot be modified "programatically".

So, the advantage is twofold here,

  • The value whenever used, will be read from the memory (cache-ing not allowed), giving you the latest updated value (if updated).
  • The value, cannot be altered, (written over) intentionally or unintentionally by the program.

Solution 4 - C

We can use the article Introduction to the volatile keyword which says:

> A variable should be declared volatile whenever its value could change > unexpectedly. In practice, only three types of variables could change: > > - Memory-mapped peripheral registers > - Global variables modified by an interrupt service routine > - Global variables within a multi-threaded application

and:

> Embedded systems contain real hardware, usually with sophisticated > peripherals. These peripherals contain registers whose values may > change asynchronously to the program flow. As a very simple example, > consider an 8-bit status register at address 0x1234. It is required > that you poll the status register until it becomes non-zero. The nave > and incorrect implementation is as follows: > > UINT1 * ptr = (UINT1 *) 0x1234; >
> // Wait for register to become non-zero. > while (*ptr == 0); > // Do something else. > > This will almost certainly fail as soon as you turn the optimizer on, > since the compiler will generate assembly language that looks > something like this: > > mov ptr, #0x1234 mov a, @ptr loop bz loop

The const says your program won't change the variable but as noted in the article outside sources could and volatile prevents it being optimized away.

Solution 5 - C

**const volatile char p=(const volatile char ) 0x30;
What is meant by: The value of p is changed by external conditions only.

Conceptually, you can think of this type of variable as a logical viewer. Similar in concept to the peephole in a door. A peephole allows you to view what is on the other side of the door, but does not allow you to change what is on the other side (const). However, conditions on the outside of the door can change on their own volition (they are volatile). You can see what happens, but you cannot change what happens.

In an embedded system, for example, there are hardware registers designed to provide state information about events happening in the outside world. An optical encoder, for example, used to sense RPM will set a value in a register. Each rotation, it senses light from an led and modifys the value in a hardware register. This is what is meant by external conditions. On the other side of the picture, i.e. in your code (perhaps a PID control loop), you can read this information to use in providing adjustments to the loop, but you cannot change this value, nor would you want to. (const)

From the perspective of your software then, this illustrates:

enter image description here

Solution 6 - C

const doesn't make a variable constant. It just make the compiler refuse some write access. This is still possible to write in the variable (via const-casted pointers for instance).

You can see const as a protection against coding mistakes.

This declaration make sure you don't inadvertently write to p, while telling the compiler not to optimize accesses (cache, out of order execution(?),...) because an external event may write in p.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionameyCUView Question on Stackoverflow
Solution 1 - CBlagovest BuyuklievView Answer on Stackoverflow
Solution 2 - CDevSolarView Answer on Stackoverflow
Solution 3 - CSourav GhoshView Answer on Stackoverflow
Solution 4 - CShafik YaghmourView Answer on Stackoverflow
Solution 5 - CryykerView Answer on Stackoverflow
Solution 6 - Cjohan dView Answer on Stackoverflow