5

In C and C++ what do the following declarations do?

const int * i;
int * const i;
const volatile int ip;
const int *i;

Are any of the above declarations wrong?

If not what is the meaning and differences between them?

What are the useful uses of above declarations (I mean in which situation we have to use them in C/C++/embedded C)?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278

2 Answers2

34

const int * i;

i is a pointer to constant integer. i can be changed to point to a different value, but the value being pointed to by i can not be changed.

int * const i;

i is a constant pointer to a non-constant integer. The value pointed to by i can be changed, but i cannot be changed to point to a different value.

const volatile int ip;

This one is kind of tricky. The fact that ip is const means that the compiler will not let you change the value of ip. However, it could still be modified in theory, e.g. by taking its address and using the const_cast operator. This is very dangerous and not a good idea, but it is allowed. The volatile qualifier indicates that any time ip is accessed, it should always be reloaded from memory, i.e. it should NOT be cached in a register. This prevents the compiler from making certain optimizations. You want to use the volatile qualifier when you have a variable which might be modified by another thread, or if you're using memory-mapped I/O, or other similar situations which could cause behavior the compiler might not be expecting. Using const and volatile on the same variable is rather unusual (but legal) -- you'll usually see one but not the other.

const int *i;

This is the same as the first declaration.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • Are you sure that volatile is guaranteed to make a read-only value reflect changes made in another thread? On what implementations? What about multi-core architectures with non-coherent caches? – Steve Jessop Oct 24 '08 at 08:51
  • 1
    If a variable is **declared** `const` (as `ip` is here), then it is undefined behaviour to remove the `const` with `const_cast` in order to modify the value. Also, volatile is not guaranteed to make changes visible to another thread. Particular compilers may make that guarantee. – Anthony Williams Oct 24 '08 at 13:51
  • Anthony is completely right. volatile does not make your variable thread-aware. also, casting away const from a variable declared const is undefined behaivor. – Johannes Schaub - litb Nov 08 '08 at 16:42
  • volatile guarantees the following AFAIK, stores and reads will not be reordered or optimized away, compiler will not assume that value will not be modified between references to the var – Hasturkun Jul 01 '09 at 09:53
  • Just a word from the world of microcontrollers: It's not at all uncommon for a register (for instance, an A/D register) to be a volatile const. Check out the default header files for HC11 and PIC chips if you have a copy of CodeWarrior lying around. – Conspicuous Compiler Jul 01 '09 at 10:51
  • `const` and "constant" are two different things. `const` means read-only. A *constant* expression is one that can (and in some cases must) be evaluated at compile time. An example of the difference: `const int r = rand();` – Keith Thompson May 27 '15 at 17:49
4

You read variables declarations in C/C++ right-to-left, so to speak.

const int *i;  // pointer to a constant int (the integer value doesn't change)

int *const i;  // constant pointer to an int (what i points to doesn't change)

const volatile int ip;  // a constant integer whose value will never be cached by the system

They each have their own purposes. Any C++ textbook or half decent resource will have explanations of each.

jjnguy
  • 136,852
  • 53
  • 295
  • 323
Ty.
  • 2,220
  • 1
  • 15
  • 14