Randomblue
Randomblue

Reputation: 116393

volatile unsigned int * const

In the following line of code, what is the purpose of the const keywords?

volatile unsigned int * const UART0DR = (unsigned int *)0x10009000;

I understand the volatile unsigned int * bit, but why is const there?

Upvotes: 6

Views: 14280

Answers (3)

Lundin
Lundin

Reputation: 214780

const and volatile are called "type qualifiers". Their syntax is one of the most confusing things in C.

First of all we have the case with an ordinary variable. You usually write the type qualifier before the variable name: const int x;, but is also fine to write it after the variable name: int const x;. The meaning is the same, the latter syntax is just there to confuse.

When declaring a pointer, you are concerned with two types: the type of the pointer itself, and the type pointed at. With ordinary pointers, this is trivial: int* x means that the pointer type is pointer-to-int, and the pointed-to-type is int.

If the pointed-to-type is const int, the pointer is declared as const int* x. The pointer is of type pointer-to-const-int, and the pointed-to type is const int. If you want to confuse everyone, you can also write int const* x, it is equivalent.

Let us say that we want the pointer itself to be constant as well. For some reason we want to block the programmer from changing the address pointed at. For example, perhaps the pointer is to be stored in read-only memory of an embedded system. A constant pointer to data, is declared as int*const x; with the const keyword after the *. The pointed-to-type in this case is int, and not const int. (I try to write the const together with the *, with no space in between, to give emphasis that the pointer is constant)

If we want the pointed-to-type to be constant as well, we would have to combine the two above declarations: const int*const x; means a constant pointer pointing at a constant int.

const int x;          // x is a constant data variable
int const x;          // x is a constant data variable

const int* x;         // x is a non-constant pointer to constant data
int const* x;         // x is a non-constant pointer to constant data 

int*const x;          // x is a constant pointer to non-constant data

const int*const x;    // x is a constant pointer to constant data

In the above examples I have used the type qualifier const. But volatile is also a type qualifier, and it behaves in exactly the same manner! It is possible to declare non-volatile pointers to volatile data etc.

And finally, it is possible to combine different type qualifiers. For example a volatile const int* is a non-constant, non-volatile pointer to volatile const data. Once again we have the wonderful option to mix the order of these to confuse, so we can also write volatile int const * or int volatile const * etc and it all means the same.

Upvotes: 16

hroptatyr
hroptatyr

Reputation: 4829

From http://cdecl.org

volatile unsigned int *const a
=>
declare a as const pointer to volatile unsigned int

Upvotes: 2

Alok Save
Alok Save

Reputation: 206616

I understand the volatile unsigned int * bit, but why is const there?

It means that the pointer is constant, which means that the pointer cannot(rather should not) point to any other address.

Note the following, constructs:

volatile unsigned int * const UART0DR = 

Pointer is constant here.


volatile unsigned int const * UART0DR = 

The pointed address is constant here.


volatile unsigned int const * const UART0DR = 

The pointed address as well as the pointer is constant in this case.

Upvotes: 6

Related Questions