Root149
Root149

Reputation: 419

const and pointers in C

The use of const with a pointer can make the pointee not modifiable by dereferencing it using the pointer in question. But why neither can I modify what the pointer is not directly pointing to?

For example:

int a = 3;
const int* ptr = &a;
*ptr = 5;

will not compile. But why does

*(ptr + 2) = 5;

also not compile? I'm not changing what the pointer is pointing to.
So do we have to say that using const with a pointer in such a way not only makes not modifiable what the pointer is pointing to (by dereferencing the pointer) but also anything else, to which the adress we get using the pointer?

I know that in the example I'm trying to access not allocated memory, but this is just for the sake of discussion.

Upvotes: 20

Views: 1158

Answers (5)

Clément
Clément

Reputation: 12927

Although other answers explain the technicalities of why it doesn't work, I'd like to offer a more general reason: it's the only thing that makes sense.

The problem is that there is no general way for the compiler to decide whether p + something is the same as p or not, because something can be arbitrarily complex. A rule like "Values pointed to by p and p + 0 are unmodifiable, but other values can still be modified" cannot be checked at compile time: imagine if you wrote:

*(p + very complex expression) = ...

should your compiler be able to figure out if very complex expression is zero? What about

int s;
scanf("%d", &s);
*(p + s) = ...

What should the compiler do in that case?

The only reasonable choice here was to make any value accessed through p unmodifiable.

Upvotes: 9

Brice M. Dempsey
Brice M. Dempsey

Reputation: 2161

Let's think about the type of the expressions.

const int* ptr = &a;

The type of ptr is const int*.

So the type of *ptr is const int. Not modifiable.

The type of (ptr + 2) is still const int* so the type of *(ptr + 2) is const int which is again not modifiable.

Upvotes: 3

Jens Gustedt
Jens Gustedt

Reputation: 78903

ptr +2 simply has the same type as ptr namely is a pointer to a const object.

Pointer arithmetic supposes that the object that is pointed to is an array of all the same base type. This type includes the const qualification.

Upvotes: 25

Philipp Murry
Philipp Murry

Reputation: 1682

Since a pointer can also be used as an array (think about argv), the compiler restricts each access in which the pointer is involved. This way the whole array is read-only.

Upvotes: 4

glglgl
glglgl

Reputation: 91027

The non-modifiability introduced by const depends on where const is written.

If you write

const int * ptr = &a;

(or int const * ptr = &a;), the const refers to the pointee, so using the pointer for writing to the destination is forbidden.

(OTOH, if wou wrote

int * const ptr = &a;

you couldn't modify ptr.)

In your case, everything involving writing to the destination is forbidden.

This includes *ptr and ptr[0] (which are equivalent), but also everything involving a modification of the destination address, such as *(ptr + 2) or ptr[2].

Upvotes: 13

Related Questions