tags:

views:

345

answers:

4

What are the differences between const and volatile pointer in C?

+1  A: 

Here's an explanation of those two concepts

The const keyword specifies that the pointer cannot be modified after initialization; the pointer is protected from modification thereafter.

The volatile keyword specifies that the value associated with the name that follows can be modified by actions other than those in the user application. Therefore, the volatile keyword is useful for declaring objects in shared memory that can be accessed by multiple processes or global data areas used for communication with interrupt service routines.

It comes from here

Tony
+1  A: 

A const pointer (i.e. const char* s = ..) points to data that can not be modified. A volatile pointer (i.e.volatile char* s = ...) hints the compiler not to cache the data the pointer refers to in CPU registers, or elsewhere. Instead, they're reread from their original memory location every time they're needed. This is needed if the contents of the data might change outside the compiler's scope, for example through a second thread modifying it.

Be careful, const char* and char* const are different things, same for the volatilequalifier. If you're unsure, look them up.

Alexander Gessler
+1  A: 

Normally, const or volatile applies to the pointee, not the pointer itself.

const means you're not allowed to modify the pointee via that pointer.

volatile means somebody/something else might modify the pointee, even though your code doesn't. It also means that writing to the variable might do something more than just store a value to be retrieved the next time that variable is used. As a result, any time your code reads or writes a volatile value, the compiler is obliged to generate code that reads from (or writes to) actual memory, not just (for example) allocates a register for temporary use, and reads/writes the register.

Edit: Note that even though you're not allowed to modify the data via a const pointer, the data may still be modified by other means. In fact, there are times that you can have a pointee that's both const and volatile, which means you can't change it, but somebody else might.

Jerry Coffin
It depends if it's `const char * p` or `char * const p`. You can quite reasonably have `const char * const p`.
Craig McQueen
+8  A: 

The difference really comes down to the difference between const and volatile. The only things these two concepts have in common is syntax. const is compiler-enforced and says "the programmer can not change this." volatile says "this data might be changed by someone else" and so the compiler will not make any assumptions about that data. Without volatile the compiler might say "I put this data from memory into a register, and since I haven't done anything to that data, I'm sure it's the same and I don't need to read it into the register again." When the data is marked as volatile the compiler won't make such an assumption (because someone else might have changed the data) and so it will reread the data into the register.

Now, are you asking for the difference between

int *const p;

and

int *volatile q;

or the difference between

const int* p;

and

volatile int* q;

In the former case: p is a pointer to an int and where that pointer points can not be changed by the programmer whereas q is a pointer to an int and where that pointer points could be changed by someone other than the programmer so the compiler makes no assumptions about that pointer.

So:

int *const p = (int*)malloc(sizeof(int));
int *volatile q = (int*)malloc(sizeof(int));
*p = 17; // legal;
p = (int*)malloc(sizoef(int)); // not legal
*q = 17; // legal;
q = (int*)malloc(sizeof(int)); // legal

In the latter case: p is a pointer to an int and what p is pointing to can not be changed by the programmer whereas q is a pointer to an int and what q is pointing to could be changed by someone other than the programmer so the compiler makes no assumptions about that data.

int i = 17;
int j = 34;
const int *p = &i;
volatile int *q = &i;
*p = 51; // not legal
p = &j; // legal
*q = 51; // legal
q = &j; // legal
Jason
Great answer! +1
the_drow
Another legitimate use for `volatile` is when the act of accessing the data is significant itself, which is reasonably likely in memory-mapped I/O. In 1.9(6) of the Standard, "observable behavior" is defined as "the sequence of reads and writes to `volatile` data and calls to library I/O functions."
David Thornley