Reputation: 116393
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
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
Reputation: 4829
From http://cdecl.org
volatile unsigned int *const a
=>
declare a as const pointer to volatile unsigned int
Upvotes: 2
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