constant pointer vs pointer on a constant value

CPointersConstants

C Problem Overview


What is the difference between the following declarations?

char * const a;
const char * a;

In order to understand the difference I wrote this small program:

#include <stdio.h>
#include <stdlib.h>


int main (int argc, char **argv)
{
    char a = 'x';
    char b = 'y';

    char * const pc1 = &a;
    const char * pc2 = &a;

    printf ("Before\n");
    printf ("pc1=%p\n", pc1);
    printf ("*pc1=%c\n", *pc1);
    printf ("pc2=%p\n", pc2);
    printf ("*pc2=%c\n", *pc2);

    *pc1 = b;
/*     pc1 = &b; */

/*     *pc2 = b; */
    pc2 = &b;
    
    printf ("\n\n");
    
    printf ("After\n");
    printf ("pc1=%p\n", pc1);
    printf ("*pc1=%c\n", *pc1);
    printf ("pc2=%p\n", pc2);
    printf ("*pc2=%c\n", *pc2);

    return EXIT_SUCCESS;
}

I compiled the program (with gcc 3.4) and ran it. The output highlights the difference rather well:

Before
pc1=ffbfd7e7
*pc1=x
pc2=ffbfd7e7
*pc2=x


After
pc1=ffbfd7e7
*pc1=y
pc2=ffbfd7e6
*pc2=x

However, I had to write the small program to get the answer. In case I'm away from the machine (at an interview for instance), I wouldn't be able to answer the question.

Can someone please explain, by commenting the above example, how the const keyword operates?

C Solutions


Solution 1 - C

char * const a;

means that the pointer is constant and immutable but the pointed data is not.
You could use const_cast(in C++) or c-style cast to cast away the constness in this case as data itself is not constant.

const char * a;

means that the pointed data cannot be written to using the pointer a. Using a const_cast(C++) or c-style cast to cast away the constness in this case causes Undefined Behavior.

Solution 2 - C

To parse complicated types, you start at the variable, go left, and spiral outwards. If there aren't any arrays or functions to worry about (because these sit to the right of the variable name) this becomes a case of reading from right-to-left.

So with char *const a; you have a, which is a const pointer (*) to a char. In other words you can change the char which a is pointing at, but you can't make a point at anything different.

Conversely with const char* b; you have b, which is a pointer (*) to a char which is const. You can make b point at any char you like, but you cannot change the value of that char using *b = ...;.

You can also of course have both flavours of const-ness at one time: const char *const c;.

Solution 3 - C

char * const a;

*a is writable, but a is not; in other words, you can modify the value pointed to by a, but you cannot modify a itself. a is a constant pointer to char.

const char * a; 

a is writable, but *a is not; in other words, you can modify a (pointing it to a new location), but you cannot modify the value pointed to by a.

Note that this is identical to

char const * a;

In this case, a is a pointer to a const char.

Solution 4 - C

Now that you know the difference between char * const a and const char * a. Many times we get confused if its a constant pointer or pointer to a constant variable.

How to read it? Follow the below simple step to identify between upper two.

Lets see how to read below declaration

char * const a;

read from Right to Left

Now start with a,

1 . adjacent to a there is const.

char * (const a);

---> So a is a constant (????).

2 . Now go along you get *

char (* (const a));

---> So a is a constant pointer to (????).

3 . Go along and there is char

(char (* (const a)));

---> a is a constant pointer to character variable

a is constant pointer to character variable. 

Isn't it easy to read?

Similarily for second declaration

const char * a;

Now again start with a,

1 . Adjacent to a there is *

---> So a is a pointer to (????)

2 . Now there is char

---> so a is pointer character,

Well that doesn't make any sense!!! So shuffle pointer and character

---> so a is character pointer to (?????)

3 . Now you have constant

---> so a is character pointer to constant variable

But though you can make out what declaration means, lets make it sound more sensible.

a is pointer to constant character variable

Solution 5 - C

The easiest way to understand the difference is to think of the different possibilities. There are two objects to consider, the pointer and the object pointed to (in this case 'a' is the name of the pointer, the object pointed to is unnamed, of type char). The possibilities are:

  1. nothing is const
  2. the pointer is const
  3. the object pointed to is const
  4. both the pointer and the pointed to object are const.

These different possibilities can be expressed in C as follows:

  1. char * a;
  2. char * const a;
  3. const char * a;
  4. const char * const a;

I hope this illustrates the possible differences

Solution 6 - C

The first is a constant pointer to a char and the second is a pointer to a constant char. You didn't touch all the cases in your code:

char * const pc1 = &a; /* You can't make pc1 point to anything else */
const char * pc2 = &a; /* You can't dereference pc2 to write. */

*pc1 = 'c' /* Legal. */
*pc2 = 'c' /* Illegal. */

pc1 = &b; /* Illegal, pc1 is a constant pointer. */
pc2 = &b; /* Legal, pc2 itself is not constant. */

Solution 7 - C

I will explain it verbally first and then with an example:

A pointer object can be declared as a const pointer or a pointer to a const object (or both):

const pointer cannot be reassigned to point to a different object from the one it is initially assigned, but it can be used to modify the object that it points to (called the "pointee").
Reference variables are thus an alternate syntax for constpointers.

A pointer to a const object, on the other hand, can be reassigned to point to another object of the same type or of a convertible type, but it cannot be used to modify any object.

const pointer to a const object can also be declared and can neither be used to modify the pointee nor be reassigned to point to another object.

Example:

void Foo( int * ptr,
		 int const * ptrToConst,
		 int * const constPtr,
		 int const * const constPtrToConst ) 
{ 
	*ptr = 0; // OK: modifies the "pointee" data 
	ptr = 0; // OK: modifies the pointer 

	*ptrToConst = 0; // Error! Cannot modify the "pointee" data
	 ptrToConst = 0; // OK: modifies the pointer 

	*constPtr = 0; // OK: modifies the "pointee" data 
	constPtr = 0; // Error! Cannot modify the pointer 

	*constPtrToConst = 0; // Error! Cannot modify the "pointee" data 
	constPtrToConst = 0; // Error! Cannot modify the pointer 
}

Happy to help! Good Luck!

Solution 8 - C

Above are great answers. Here is an easy way to remember this:

a is a pointer

*a is the value

Now if you say "const a" then the pointer is const. (i.e. char * const a;)

If you say "const *a" then the value is const. (i.e. const char * a;)

Solution 9 - C

You may use cdecl utility or its online versions, like https://cdecl.org/

For example:

void (* x)(int (*[])()); is a declare x as pointer to function (array of pointer to function returning int) returning void

Solution 10 - C

Trying to answer in simple way:

char * const a;  => a is (const) constant (*) pointer of type char {L <- R}. =>( Constant Pointer )
const char * a;  => a is (*) pointer to char constant             {L <- R}. =>( Pointer to Constant)

Constant Pointer:

pointer is constant !!. i.e, the address it is holding can't be changed. It will be stored in read only memory.

Let's try to change the address of pointer to understand more:

char * const a = &b; 
char c;
a = &c; // illegal , you can't change the address. `a` is const at L-value, so can't change. `a` is read-only variable.

It means once constant pointer points some thing it is forever.

pointer a points only b.

However you can change the value of b eg:

char b='a';
char * const a =&b;

printf("\n print a  : [%c]\n",*a);
*a = 'c';
printf("\n now print a  : [%c]\n",*a);

Pointer to Constant:

Value pointed by the pointer can't be changed.

const char *a;
char b = 'b';
const char * a =&b;
char c;
a=&c; //legal

*a = 'c'; // illegal , *a is pointer to constant can't change!.

Solution 11 - C

const char * a;

This states pointer to constant character. For eg.

char b='s';
const char *a = &b;

Here a points to a constant char('s',in this case).You can't use a to change that value.But this declaration doesn't mean that value it points to is really a constant,it just means the value is a constant insofar as a is concerned. You can change the value of b directly by changing the value of b,but you can't change the value indirectly via the a pointer.

*a='t'; //INVALID b='t' ; //VALID

char * const a=&b

This states a constant pointer to char. It constraints a to point only to b however it allows you to alter the value of b.

Hope it helps!!! :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrahmuView Question on Stackoverflow
Solution 1 - CAlok SaveView Answer on Stackoverflow
Solution 2 - CAATView Answer on Stackoverflow
Solution 3 - CJohn BodeView Answer on Stackoverflow
Solution 4 - CSagar SakreView Answer on Stackoverflow
Solution 5 - CJohn VincentView Answer on Stackoverflow
Solution 6 - CcnicutarView Answer on Stackoverflow
Solution 7 - CBarelView Answer on Stackoverflow
Solution 8 - CjackView Answer on Stackoverflow
Solution 9 - CZinovy NisView Answer on Stackoverflow
Solution 10 - CB_SanView Answer on Stackoverflow
Solution 11 - Cuser4291320View Answer on Stackoverflow