Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a pointer be volatile?

Consider the following code:

int square(volatile int *p)
{
    return *p * *p;
}

Now, the volatile keyword indicates that the value in a memory location can be altered in ways unknown to the compiler or have other unknown side effects (e.g. modification via a signal interrupt, hardware register, or memory mapped I/O) even though nothing in the program code modifies the contents.

So what exactly happens when we declare a pointer as volatile?

Will the above mentioned code always work, or is it any different from this:

int square(volatile int *p)
{
    int a = *p;
    int b = *p
    return a*b;
}

Can we end up multiplying different numbers, as pointers are volatile?

Or is there better way to do so?

like image 603
vishal Avatar asked Oct 22 '15 12:10

vishal


People also ask

Can we have a volatile pointer in C?

Volatile is used in C programming when we need to go and read the value stored by the pointer at the address pointed by the pointer. If you need to change anything in your code that is out of compiler reach you can use this volatile keyword before the variable for which you want to change the value.

What is pointer to constant volatile data?

An object marked as const volatile will not be permitted to be changed by the code (an error will be raised due to the const qualifier) - at least through that particular name/pointer. The volatile part of the qualifier means that the compiler cannot optimize or reorder access to the object.

Do pointers have memory?

Yes, a declared pointer has its own location in memory.

Can a parameter be both const and volatile?

Yes a C++ variable be both const and volatile. It is used in situations like a read-only hardware register, or an output of another thread. Volatile means it may be changed by something external to the current thread and Const means that you do not write to it (in that program that is using the const declaration).


5 Answers

Can a pointer be volatile?

Absolutely; any type, excluding function and references, may be volatile-qualified.

Note that a volatile pointer is declared T *volatile, not volatile T*, which instead declares a pointer-to-volatile.

A volatile pointer means that the pointer value, that is its address and not the value pointed to by, may have side-effects that are not visible to the compiler when it's accessed; therefore, optimizations deriving from the "as-if rule" may not be taken into account for those accesses.


int square(volatile int *p) { return *p * *p; }

The compiler cannot assume that reading *p fetches the same value, so caching its value in a variable is not allowed. As you say, the result may vary and not be the square of *p.

Concrete example: let's say you have two arrays of ints

int a1 [] = { 1, 2, 3, 4, 5 };
int a2 [] = { 5453, -231, -454123, 7565, -11111 };

and a pointer to one of them

int * /*volatile*/ p = a1;

with some operation on the pointed elements

for (int i = 0; i < sizeof(a1)/sizeof(a1[0]); ++i) 
       *(p + i) *= 2;

here p has to be read each iteration if you make it volatile because, perhaps, it may actually point to a2 due to external events.

like image 113
edmz Avatar answered Sep 20 '22 13:09

edmz


Yes, you can of course have a volatile pointer.

Volatile means none more and none less than that every access on the volatile object (of whatever type) is treated as a visible side-effect, and is therefore exempted from optimization (in particular, this means that accesses may not be reordered or collapsed or optimized out alltogether). That's true for reading or writing a value, for calling member functions, and of course for dereferencing, too.

Note that when the previous paragraph says "reordering", a single thread of execution is assumed. Volatile is no substitute for atomic operations or mutexes/locks.

In more simple words, volatile generally translates to roughly "Don't optimize, just do exactly as I say".

In the context of a pointer, refer to the exemplary usage pattern given by Chris Lattner's well-known "What every programmer needs to know about Undefined Behavior" article (yes, that article is about C, not C++, but the same applies):

If you're using an LLVM-based compiler, you can dereference a "volatile" null pointer to get a crash if that's what you're looking for, since volatile loads and stores are generally not touched by the optimizer.

like image 38
Damon Avatar answered Sep 22 '22 13:09

Damon


Yes. int * volatile.

In C++, keywords according to type/pointer/reference go after the token, like int * const is constant pointer to integer, int const * is pointer to constant integer, int const * const is constant pointer to constant integer e.t.c. You can write keyword before the type only if it's for the first token: const int x is equal to int const x.

like image 40
Lapshin Dmitry Avatar answered Sep 20 '22 13:09

Lapshin Dmitry


The volatile keyword is a hint for the compiler (7.1.6.1/7):

Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. Furthermore, for some implementations, volatile might indicate that special hardware instructions are required to access the object. See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same in C ++ as they are in C. — end note ]

What does it mean? Well, take a look at this code:

bool condition = false;
while(!condition)
{
    ...
}

by default, the compiler will easilly optimize the condition out (it doesn't change, so there is no need to check it at every iteration). If you, however, declare the condition as volatile, the optimization will not be made.

So of course you can have a volatile pointer, and it is possible to write code that will crash because of it, but the fact that a variable is volative doesn't mean that it is necessarily going to be changed due to some external interference.

like image 35
SingerOfTheFall Avatar answered Sep 21 '22 13:09

SingerOfTheFall


Yes, a pointer can be volatile if the variable that it points to can change unexpectedly even though how this might happen is not evident from the code.

An example is an object that can be modified by something that is external to the controlling thread and that the compiler should not optimize.

The most likely place to use the volatile specifier is in low-level code that deals directly with the hardware and where unexpected changes might occur.

like image 44
dspfnder Avatar answered Sep 23 '22 13:09

dspfnder