1

Let

int i = 1;
const int *p = &i;

Why can I change i but not *p? Or rather, what happens behind the scenes that allows me to write i = 5 but not *p = 5?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Nix
  • 77
  • 1
  • 10
  • Why can't you change it through the pointer? Because you said it's a pointer for a **const** int, and you can't change constants. – Blaze Feb 06 '20 at 08:11
  • @Blaze I'm trying to understand how though, how can the compiler differentiate between the pointer and the value, given the pointer just points to the non-constant value? – Nix Feb 06 '20 at 08:12
  • 1
    A `const` pointer is a pointer whose referred value cannot be changed _through that pointer_. Nothing prevents that value from changing by other means. – bereal Feb 06 '20 at 08:13
  • 1
    *"how can the compiler differentiate between the pointer and the value, given the pointer just points to the non-constant value?"* -- why wouldn't it be able to do that? This happens at compile time. It sees the `*p = 5`, it knows that `p` is a pointer to `const int` and then you get the error. – Blaze Feb 06 '20 at 08:15
  • @Blaze, this means a simple cast like `((int*)p) = 5` would work.?! – Holger Feb 06 '20 at 08:19
  • This is in front of the scenes as it were... `*p` has type `const int` therefore an error is generated if the assignment operator is applied to it – M.M Feb 06 '20 at 08:19
  • The point is simply: `i` is a non constant variable so you can change it, `p` is a pointer to something that **should not be changed**. At this point the compiler, as stated by language, doesn't care **to what you point** (constant or not constant), but prevent you from any change. – Frankie_C Feb 06 '20 at 08:21
  • `((int*)p) = 5`? You mean `*((int*)p) = 5`? Yeah, that works. It shouldn't even be undefined behavior because you take an `int*`, assign it to a `const int*` and then cast it back to an `int*`. But what's the point of that? – Blaze Feb 06 '20 at 08:25
  • 1
    Does this answer your question? [Dereferencing a pointer to constant](https://stackoverflow.com/questions/50458812/dereferencing-a-pointer-to-constant) –  Feb 06 '20 at 08:30

4 Answers4

1

By declaring p as a pointer to const int you are making promise to compiler to not to modify the object pointed by p using dereference through p. It's on you if you are keeping your promise or break it by changing the object pointed by p by other means.

haccks
  • 104,019
  • 25
  • 176
  • 264
1

There is nothing behind the scene. Everything is on the complier side.

i denotes an identifier that references a memory chunk able to store an int value. Through that i you can either read or write.

p denotes a pointer to a const int. That only means that through p you are not able to write the pointed int, only read. p is a view to an int which let not you modify it. That's all. And this is a property ensured at compilation.

Now think of definition/declaration as typed access to memory tainted with access rights.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
1

First of all it is not const pointer only pointer to const object.

In the fact you just promise the compiler that you do not want object referenced by the pointer to be changed by the dereference of this pointer. Compiler will trace (but only compiler) attempts to assign new value to the object in the source code. There is no runtime check and you can of course (if the object is not in the read only memory) change it by tricking the compiler in the source code.

0___________
  • 60,014
  • 4
  • 34
  • 74
1

You told the compiler "I am not going to try assigning to *p" (that is really all there is to const), but that says nothing about i.

#include <stdio.h>
void main(void) {
  int i = 1;
  const int *p = &i;
  printf("i=%d\np*=%d\n", i, p);
  i = 5;
  printf("i=%d\np*=%d\n", i, p);
  *p = 10;
  printf("i=%d\np*=%d\n", i, p);
}

GCC will complain about assignment of read-only location '*p', but i=5 is fine, since i is not const. Remove the const from *p, or remove the assignment *p=10, and everything is good.

If the reference to i were to somehow disappear, then that memory space would effectively become read-only from the programmer's perspective: the compiler won't let me write to *p, and that is the only handle I have left for that piece of memory.

Z4-tier
  • 7,287
  • 3
  • 26
  • 42