3

I have written this piece of code

#include <stdio.h>
int main() {
     int b = 15;
     const int *foo = &b;
     //b = 20;
     *foo = 20;
     printf("%d", *foo);
     return 0;
}

This means that the location that foo is pointing to cannot change. That means b cannot change . But when I uncomment the line b = 20. It doesn't show any error and I get the output 20 . While in this piece of code I get this error

main.c: In function 'main':
main.c:15:10: error: assignment of read-only location '*foo'
      *foo = 20;

If *foo that is b is read only location, why can I change its value b = 20?

haccks
  • 104,019
  • 25
  • 176
  • 264
  • Take a look at [this answer](https://stackoverflow.com/a/890846/4824627) which I believe will help you understand why this is doing what it is doing – Matheus Avellar Aug 19 '17 at 19:45
  • You can't use `foo` to change what it points at. There's nothing to stop you from changing what's pointed at by other legitimate mechanisms. Using `b` is a legitimate mechanism to modify the location pointed at by `foo`. – Jonathan Leffler Aug 19 '17 at 19:49
  • Possible duplicate of [What is the difference between char \* const and const char \*?](https://stackoverflow.com/questions/890535/what-is-the-difference-between-char-const-and-const-char) – MikeMB Aug 19 '17 at 20:13
  • Please read the whole question ! – Pradeep Kumar Aug 19 '17 at 20:16
  • @MikeMB; No, its not. – haccks Aug 19 '17 at 20:18
  • @haccks Constant variables are stored in write-protected region of the stack segment . Stack because it is declared in the main() function ! – Pradeep Kumar Aug 19 '17 at 20:26
  • 1
    @PradeepKumar *is* there a write-protected region of the stack segment? If so, it would need to be many fragmented regions of the typical stack frame (in some implementation). My understanding is it's an instruction to the compiler. – Weather Vane Aug 19 '17 at 20:29
  • https://stackoverflow.com/questions/1576489/where-are-constant-variables-stored-in-c – Pradeep Kumar Aug 19 '17 at 20:31
  • I dont know much but this region must be existing till the time of execution of the function then cleaned out along with other local variables ! – Pradeep Kumar Aug 19 '17 at 20:32
  • C does not mandate any physical hardware or even a stack. – Weather Vane Aug 19 '17 at 20:36
  • It has got a stack section in main memory when the program is loaded there for supporting recursion ! – Pradeep Kumar Aug 19 '17 at 20:43
  • Yes, but C says nothing about physical write-protection, segments or stacks. – Weather Vane Aug 19 '17 at 20:45

5 Answers5

8

What does

 int b=15;
 const int* foo=&b;   

mean?

It means,

  • b is a modifiable int object.
  • &b has type int *. The declaration for foo converts &b to type const int *. This is a valid qualification conversion.
  • int object pointed by foo must not be modified using foo.

The above qualification conversion does not invalidates the declaration of b, i.e. it still is modifiable. b can still be used to update its value but *foo can't be used.

Think const as a promise. You promised the compiler that you will not change the value at the location pointed by foo, but no one is stopping you to break that promise by changing that value at that location by other means.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • That is the question . foo points to b . I can set it as b=20 and I dont get any error ! – Pradeep Kumar Aug 19 '17 at 19:36
  • 2
    You can't use `foo` to change what it points at. There's nothing to stop you from changing what's pointed at by other legitimate mechanisms. Using `b` is a legitimate mechanism to modify the location pointed at by `foo`. – Jonathan Leffler Aug 19 '17 at 19:48
  • b is just the name given to the value stored in memory (location in memory) . The error says that is read only . How can we change its value then ? Sorry but I am not getting it ! – Pradeep Kumar Aug 19 '17 at 19:51
  • 2
    @PradeepKumar: We can see that you're not getting it. What's hard is working out why you're not getting it. That `foo` is a pointer to a constant value means that you can't use `foo` to change what it points at. But `b` is not constant. It can be changed. It just can't be changed using `foo`. – Jonathan Leffler Aug 19 '17 at 19:55
  • @PradeepKumar; I changed the answer and explained it further. Read it again. – haccks Aug 19 '17 at 20:02
  • On Xcode it says this "Read-Only variable is not assignable " – Pradeep Kumar Aug 19 '17 at 20:17
  • @PradeepKumar; There is a bar that says "Alcohol will be served to 18+ only". Now think the location of `b` as a bar. `b` is 18+ and is allowed to go there and do whatever it wants. `foo` on the other hand is allowed to go their but restricted to not have alcohol. If it will ask for alcohol then it will be reminded that *"Alcohol will be served to 18+ only"*. – haccks Aug 19 '17 at 20:23
  • @PradeepKumar; Yes. It is misleading. – haccks Aug 19 '17 at 20:50
  • Why they call it pointer to a constant when we change it by other means ! – Pradeep Kumar Aug 19 '17 at 21:04
  • @PradeepKumar; it is to inform the compiler that you will not modify the value by using that particular mean. – haccks Aug 19 '17 at 21:08
7

I think chqrlie is right when he says that the error message "assignment of read-only location '*foo'" is misleading. Actually, const int *foo (i.e. a pointer defined as pointing to a const int) does not mean that the memory addressed by the pointer is or becomes immutable per se; it just means that the memory addressed by the pointer must not be changed through this pointer; it might, however, be changed in other ways. You could define, for example a second pointer int *foo2 = &b through which you may change the value addressed by foo2.

So you may think of the pointer as being a separate view to a value at a particular memory address, and one may declare the view as read-only or not. This does, however, not effect whether the value at the particular memory address per se is immutable or not:

int main()
{
    int b=15;  // b is mutable
    const int* foo=&b; // *foo is immutable; b remains mutable
    int *foo2=&b; // *foo2 is mutable
    b=20;  // allowed, since b is mutable
    *foo=20; // not allowed, since "*foo" is immutable, even if the value to which it points (i.e. b) would be mutable
    *foo2=20; // allowed, since "*foo2" is mutable

    return 0;
}

Though not asked, the other way round, you actually may define a value as being immutable, and this value must then not be altered in any way; if you somehow manipulated the value by writing to its memory address, the behaviour is undefined:

const int c = 15; // c is immutable
int* bar = &c; // warning: discards const qualifier
printf("%d\n", c);
*bar = 20;  // undefined behaviour from here on; modifying a const value is not allowed.
printf("%d\n", c); // undefined behaviour; good chance that it still prints 15, because a compiler might have relied on the fact that c is 15 and immutable
printf("%d\n", *bar); // undefined behaviour; probably printing 20?

Hope it helps.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • Thank you for your answer but how can we have two separate views of the main memory ! – Pradeep Kumar Aug 19 '17 at 20:22
  • You may have as many pointers as you want, all pointing the the same address of main memory, if you like. – Stephan Lechner Aug 19 '17 at 20:27
  • @PradeepKumar a pointer is simply a variable that holds the address of something else as its value. You can have many pointers all holding the same address (pointing to the same something else). "*views*" may not be the best word, but it accurately describes your ability to view the same bits in memory through multiple pointers if they all point at those bits. – David C. Rankin Aug 19 '17 at 20:53
3

No, const int* foo = &b; doesnt mean you cant change b, it means that you cant dereference this pointer and change value of dereferenced pointer like this

*foo = 20;

You cant say with const that some piece of memory is unmodificable for all. You can say that only that const variable cant change this piece of memory, so this operation (if b hasnt const modifier) is perfectly valid even if you have const pointer pointing to b.

 b=20;
kocica
  • 6,412
  • 2
  • 14
  • 35
  • @Filip Kočica IMO it is "T" - word question – 0___________ Aug 19 '17 at 19:45
  • 1
    @PradeepKumar: the error message says `*foo` is a read only location because `foo` is defined as pointing to a location that should not be changed via this pointer. The error message is somewhat confusing. – chqrlie Aug 19 '17 at 19:59
  • @chqrlie: good point, the error message is misleading and likely to be the root cause for OP's misinterpretation of the meaning of the code. – Stephan Lechner Aug 19 '17 at 20:12
  • there is a difference between the pointer declaration and object declaration. The pointer cant be used to change the referenced object. The object itself can be changed, but not via the const pointer – 0___________ Aug 19 '17 at 20:14
  • The point here is that pointer to non-const can be seamlesslly converted to pointer to a const of same type. This is interpreted just as intent NOT to modify the value thru this pointer. The original lvalue, of course, is not affected by adding a new pointer to it and remains writable. – ddbug Aug 19 '17 at 20:35
0

If you want a constant pointer to not constant object declare it:

 T * const ptr = &t

Where T is the type of the object and t is the object itself

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

The answer to this question is after declaring the pointer as

const int *foo = &b;

you cant use *foo as a L-value because this code also gives the same error

#include <stdio.h>
int main() {
     int a=10,b = 15;
     const int *foo = &b;
     foo=&a; //assigning foo the address of a
     *foo=30; // Again here you cant use *foo
     printf("%d", *foo);
     return 0;
}