3

So this is just a duplicate of:

What is the difference between char * const and const char *?

What's the difference between:

char * const 

and

const char *

But I still do not get it.

So given the first answer:

The difference is that const char * is a pointer to a const char, while char * const is a constant pointer to a char.

The first, the value being pointed to can't be changed but the pointer can be. The second, the value being pointed at can change but the pointer can't (similar to a reference).

Ok so, I have coded this to:

//exercises
char* barfoo = "variable_test";

const char* my_pointer_to_const_char = barfoo; //"barfoo" can't be changed but the pointer to it, can!

barfoo = "changed!";
std::cout<< barfoo << std::endl;

So according to the answer above, barfoo can't be changed? I have changed it in my code, and it prints "changed". I don't understand shouldn't it be throwing an error ?

Can you please give me a correct example, because I am doing something wrong clearly.

Trt Trt
  • 5,330
  • 13
  • 53
  • 86

2 Answers2

4

You are missing two key concepts in your understanding.

A pointer, and the "thing" the pointer is pointing to. They are two separate, discrete "things". The pointer itself. And whatever the pointer is pointing to. That's the first key concept.

The second key concept is that either one, or the other, can be const. Or both can be const. Whatever's const, cannot be changed.

If the pointer itself is const, you can't change the pointer. It will always point to the same "thing", until the pointer goes out of scope and gets destroyed. But, even if the pointer is const, you can use this pointer to modify its "thing" unless the "thing" itself is const.

If the pointer is a pointer to a const "thing" you cannot change the "thing" using this pointer. But you can change the pointer to point to a different const "thing".

Or, even if the pointer is, allegedly, is a pointer to a const "thing", if there's another pointer that's pointing to the same "thing", and the other pointer may not necessarily be a pointer to a const "thing"; it could be a non-const pointer. In that situation, the other pointer can be used to change the same "thing" (because, after all, it is not a pointer to some const thing). And now, even though the first pointer is a pointer to const thing, the const thing it's pointing to has now changed. And this leads to an arcane discussion about aliasing rules that are better left for some other day...

But, back to the subject matter at hand:

char* barfoo = "variable_test";

const char* my_pointer_to_const_char = barfoo; //"barfoo" can't be changed but the pointer to it, can!

barfoo = "changed!";

Here, you changed one of the pointers, itself. You did not change whatever the pointer is pointing to. The literal string "variable_test" is still "there", wherever that "there" is, and the const pointer is still pointing to it. Whatever you do to one pointer, has no effect on the other pointer. They are different "thing"s.

You need to undergo a slight mental shift. You need to clearly separate, in your mind, the pointer itself, from whatever the pointer is pointing to.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • "And this leads to an arcane discussion about aliasing rules that are better left for some other day..." ahah good one! ny way thanks really good answer! it helped! – Trt Trt Oct 15 '17 at 15:39
  • Like you said, "The literal string "variable_test" is still "there"", how can I find where it is and change it ? I might sound stupid, but i want an example where the IDE or compiler says to me that I can't change this because it is constant. – Trt Trt Oct 15 '17 at 16:03
  • The literal string is, by definition, `const`. A compiler may let you assign it to a `char *`, and give you a stern warning. You may be able to compile code that modifies it. And that code may run without crashing. But it will still be undefined behavior. – Sam Varshavchik Oct 15 '17 at 22:51
0

We know that pointers store the address values of their operands.

As an example, if char *ptr=a, ptr will store the address of variable a. And any variable defined as a constant cannot change its value. If const int a=5, then any statement like a++ is invalid because this will alter the value of a which is prohibited.

Similarly if a pointer ptr points to variable a with declaration const int *ptr=a. Statements like ptr=b will be invalid because ptr cannot point to b as it is a constant pointer pointing to a.

Having understood that, there happen to be two combinations of constants and pointers.

TYPE 1: Pointer to a constant

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

In this case, the variable is a constant whose value cannot be modified. Suppose the memory address of a is 0x9978. Since, pointer stores address of variable, ptr=0x9978.

Analyse the following statements:-

a=6; //Invalid: Value of a cannot be changed
*ptr=9; //Invalid: *ptr refers to a and will change its value. 
int b=t;
ptr=b;//Valid: ptr is not constant and can point anywhere

Hope this concept is clear now.

TYPE 2: Constant pointer

Here the pointer is constant. Once it is pointed to a variable, it cannot point to any other variable. It stores a constant address throughout its life time.

int a=7;
const int* ptr=a;

Here the value of ptr(0x9978) cannot be modified. See the statements again:-

a=6; //Valid: Value of a can be changed
*ptr=9; //Valid: *ptr refers to a and its value can be altered. 
int b=t;
ptr=b;//InValid: ptr is constant and cannot point anywhere else.

Thus, ptr cannot point to any other variable now.
Coming to your question, to understand better, consider char * not as a pointer but as a variable of string type(character buffer)!

char* barfoo = "variable_test"; //barfoo is a string storing 'variable_test'
const char* my_pointer_to_const_char = barfoo; 
// This is type 2, constant pointer. Thus, my_pointer_to_const_char cannot 
//point to any other variable and will always store the address of barfoo
barfoo = "changed!";
//this is perfectly valid as this statement will alter the value of string 
//barfoo. my_pointer_to_const_char will still store the address of barfoo.

If there are still any doubts, feel free to comment:)

random-parts
  • 2,137
  • 2
  • 13
  • 20