What's the difference between:
char * const
and
const char *
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).
There is also a
const char * const
which is a constant pointer to a constant char (so nothing about it can be changed).
Note:
The following two forms are equivalent:
const char *
and
char const *
The exact reason for this is described in the C++ standard, but it's important to note and avoid the confusion. I know several coding standards that prefer:
char const
over
const char
(with or without pointer) so that the placement of the const element is the same as with a pointer const.
To avoid confusion, always append the const qualifier.
int * mutable_pointer_to_mutable_int;
int const * mutable_pointer_to_constant_int;
int *const constant_pointer_to_mutable_int;
int const *const constant_pointer_to_constant_int;
const always modifies the thing that comes before it (to the left of it), EXCEPT when it's the first thing in a type declaration, where it modifies the thing that comes after it (to the right of it).
So these two are the same:
int const *i1;
const int *i2;
they define pointers to a const int. You can change where i1 and i2 points, but you can't change the value they point at.
This:
int *const i3 = (int*) 0x12345678;
defines a const pointer to an integer and initializes it to point at memory location 12345678. You can change the int value at address 12345678, but you can't change the address that i3 points to.
const char* is a pointer to a constant character
char* const is a constant pointer to a character
const char* const is a constant pointer to a constant character
const * char is invalid C code and is meaningless. Perhaps you meant to ask the difference between a const char * and a char const *, or possibly the difference between a const char * and a char * const?
See also:
What are const pointers (as opposed to pointers to const objects)?
Const in C
Difference between const declarations in C++
C++ const question
Why can I change the values of a const char* variable?
Rule of thumb: read the definition from right to left!
const int *foo;
Means "foo points (*) to an int that cannot change (const)".
To the programmer this means "I will not change the value of what foo points to".
*foo = 123; or foo[0] = 123; would be invalid.
foo = &bar; is allowed.
int *const foo;
Means "foo cannot change (const) and points (*) to an int".
To the programmer this means "I will not change the memory address that foo refers to".
*foo = 123; or foo[0] = 123; is allowed.
foo = &bar; would be invalid.
const int *const foo;
Means "foo cannot change (const) and points (*) to an int that cannot change (const)".
To the programmer this means "I will not change the value of what foo points to, nor will I change the address that foo refers to".
*foo = 123; or foo[0] = 123; would be invalid.
foo = &bar; would be invalid.
const char* x Here X is basically a character pointer which is pointing to a constant value
char* const x is refer to character pointer which is constant, but the location it is pointing can be change.
const char* const x is combination to 1 and 2, means it is a constant character pointer which is pointing to constant value.
const *char x will cause a compiler error. it can not be declared.
char const * x is equal to point 1.
the rule of thumb is if const is with var name then the pointer will be constant but the pointing location can be changed , else pointer will point to a constant location and pointer can point to another location but the pointing location content can not be change.
Another thumb rule is to check where const is:
before * => value stored is constant
after * => pointer itself is constant
First one is a syntax error. Maybe you meant the difference between
const char * mychar
and
char * const mychar
In that case, the first one is a pointer to data that can't change, and the second one is a pointer that will always point to the same address.
Lots of answer provide specific techniques, rule of thumbs etc to understand this particular instance of variable declaration. But there is a generic technique of understand any declaration:
Clockwise/Spiral Rule
A)
const char *a;
As per the clockwise/spiral rule a is pointer to character that is constant. Which means character is constant but the pointer can change. i.e. a = "other string"; is fine but a[2] = 'c'; will fail to compile
B)
char * const a;
As per the rule, a is const pointer to a character. i.e. You can do a[2] = 'c'; but you cannot do a = "other string";
Here is a detailed explanation with code
/*const char * p;
char * const p;
const char * const p;*/ // these are the three conditions,
// const char *p;const char * const p; pointer value cannot be changed
// char * const p; pointer address cannot be changed
// const char * const p; both cannot be changed.
#include<stdio.h>
/*int main()
{
const char * p; // value cannot be changed
char z;
//*p = 'c'; // this will not work
p = &z;
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
char * const p; // address cannot be changed
char z;
*p = 'c';
//p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
const char * const p; // both address and value cannot be changed
char z;
*p = 'c'; // this will not work
p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
char * const and const char *?
Pointing to a constant value
const char * p; // value cannot be changed
Constant pointer to a value
char * const p; // address cannot be changed
Constant pointer to a constant value
const char * const p; // both cannot be changed.
I presume you mean const char * and char * const .
The first, const char *, is a pointer to a constant character. The pointer itself is mutable.
The second, char * const is a constant pointer to a character. The pointer cannot change, the character it points to can.
And then there is const char * const where the pointer and character cannot change.
// Some more complex constant variable/pointer declaration.
// Observing cases when we get error and warning would help
// understanding it better.
int main(void)
{
char ca1[10]= "aaaa"; // char array 1
char ca2[10]= "bbbb"; // char array 2
char *pca1= ca1;
char *pca2= ca2;
char const *ccs= pca1;
char * const csc= pca2;
ccs[1]='m'; // Bad - error: assignment of read-only location ‘*(ccs + 1u)’
ccs= csc; // Good
csc[1]='n'; // Good
csc= ccs; // Bad - error: assignment of read-only variable ‘csc’
char const **ccss= &ccs; // Good
char const **ccss1= &csc; // Bad - warning: initialization from incompatible pointer type
char * const *cscs= &csc; // Good
char * const *cscs1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc= &pca1; // Good
char ** const cssc1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc2= &csc; // Bad - warning: initialization discards ‘const’
// qualifier from pointer target type
*ccss[1]= 'x'; // Bad - error: assignment of read-only location ‘**(ccss + 8u)’
*ccss= ccs; // Good
*ccss= csc; // Good
ccss= ccss1; // Good
ccss= cscs; // Bad - warning: assignment from incompatible pointer type
*cscs[1]= 'y'; // Good
*cscs= ccs; // Bad - error: assignment of read-only location ‘*cscs’
*cscs= csc; // Bad - error: assignment of read-only location ‘*cscs’
cscs= cscs1; // Good
cscs= cssc; // Good
*cssc[1]= 'z'; // Good
*cssc= ccs; // Bad - warning: assignment discards ‘const’
// qualifier from pointer target type
*cssc= csc; // Good
*cssc= pca2; // Good
cssc= ccss; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cscs; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cssc1; // Bad - error: assignment of read-only variable ‘cssc’
}
Constant pointer: A constant pointer can point only to a single variable of the respective data type during the entire program.we can change the value of the variable pointed by the pointer. Initialization should be done during the time of declaration itself.
Syntax:
datatype *const var;
char *const comes under this case.
/*program to illustrate the behaviour of constant pointer */
#include<stdio.h>
int main(){
int a=10;
int *const ptr=&a;
*ptr=100;/* we can change the value of object but we cannot point it to another variable.suppose another variable int b=20; and ptr=&b; gives you error*/
printf("%d",*ptr);
return 0;
}
Pointer to a const value: In this a pointer can point any number of variables of the respective type but we cannot change the value of the object pointed by the pointer at that specific time.
Syntax:
const datatype *varor datatype const *var
const char* comes under this case.
/* program to illustrate the behavior of pointer to a constant*/
#include<stdio.h>
int main(){
int a=10,b=20;
int const *ptr=&a;
printf("%d\n",*ptr);
/* *ptr=100 is not possible i.e we cannot change the value of the object pointed by the pointer*/
ptr=&b;
printf("%d",*ptr);
/*we can point it to another object*/
return 0;
}
The const modifier is applied to the term immediately to its left. The only exception to this is when there is nothing to its left, then it applies to what is immediately on its right.
These are all equivalent ways of saying "constant pointer to a constant char":
const char * const
const char const *
char const * const
char const const *
Two rules
If const is between char and *, it will affect the left one.
If const is not between char and *, it will affect the nearest one.
e.g.
char const *. This is a pointer points to a constant char.
char * const. This is a constant pointer points to a char.
I would like to point out that using int const * (or const int *) isn't about a pointer pointing to a const int variable, but that this variable is const for this specific pointer.
For example:
int var = 10;
int const * _p = &var;
The code above compiles perfectly fine. _p points to a const variable, although var itself isn't constant.
I remember from Czech book about C: read the declaration that you start with the variable and go left.
So for
char * const a;
you can read as: "a is variable of type constant pointer to char",
char const * a;
you can read as: "a is a pointer to constant variable of type char. I hope this helps.
Bonus:
const char * const a;
You will read as a is constant pointer to constant variable of type char.
Related
I have been looking at a source code, and i came across this code
static char const *const delimit_method_string[] =
{
"none", "prepend", "separate", NULL
};
I thought I knew the meaning of const keyword in the C language but after seeing this syntax I am confused as I can't decode the meaning of the syntax, so I wanted to know the meaning of using const like this I searched internet I saw some questions like this in stackoverflow that are,
Meaning of two const in C/C++ signature
Double const declaration
But still I don't understand what's the meaning of the syntax in that code snippet, may be that because I am not good enough with fundamentals of C but I really like to improve it.
So I wrote some code to know how that syntax works, this is what I tried:
#include <stdio.h>
int main()
{
char a = 'A';
char b = 'B';
char const * const ptr = &a;
ptr = &b;
printf("a is %c\n", *ptr);
printf("a is %c", a);
return 0;
}
I got this output, that somewhat I expected.
$ gcc test.c
test.c: In function 'main':
test.c:9:13: error: assignment of read-only variable 'ptr'
9 | ptr = &b;
|
^
I changed the code and tested again,
#include <stdio.h>
int main()
{
char a = 'A';
char b = 'B';
char const const *ptr = &a;
ptr = &b;
printf("a is %c\n", *ptr);
printf("a is %c", a);
return 0;
}
this time the output is not what I expected,
$ ./a.exe
a is B
a is A
I really appreciate if someone can explain what is the correct way of using const in C and also how the syntax in first code snippet works.
This declaration
static char const *const delimit_method_string[] =
{
"none", "prepend", "separate", NULL
};
declares an array with the name delimit_method_string of pointers to string literals.
In C opposite to C++ string literals have types of non-constant character arrays. Nevertheless you may not change a string literal. Any attempt to change a string literal results in undefined behavior. So it is better to declare pointers to string literals the following way as for example
const char *s = "Hello";
So you could declare the above array like
static char const * delimit_method_string[] =
{
"none", "prepend", "separate", NULL
};
But the programmer who declared this array also wanted to declare at as a constant array. That is he wanted that its elements can not be changed.
For the declaration above you can write for example
delimit_method_string[0] = "all";
To prevent such a changing elements of the array must be constant. To do this you need to write
static char const * const delimit_method_string[] =
{
"none", "prepend", "separate", NULL
};
Now the elements of the array that have the pointer type const char * are constant due to the second qualifier const.
Tom make it more clear consider the following declarations.
char *p;
This declaration declares a non-constant pointer to a non-constant object of the type char.
const char *p;
This declaration declares a non-constant pointer to a constant object of the type char.
const char * const p;
This declaration declares a constant pointer to a constant object of the type char.
The last declaration may be rewritten like
const char ( * const p );
As for this your declaraion
char const const *ptr = &a;
then on of the two qualifiers const is redundant because the both refer to the type specifier char.
char const const *ptr = &a;
This double const does not have any special meaning as both are on the same side of the *. Additional const qualifiers are ignored by the compiler. You can write char const const const const const*ptr = &a; It is the same as char const *ptr = &a; which means:
pointer to constant character
If we change it to
char const * const ptr = &a;
It will mean:
constant pointer to constant char
Your snippet will stop to compile: https://godbolt.org/z/sM9qnv8fq
examples:
const int *ptr; - pointer to constant integer
int * const ptr; - constant pointer to integer
const int * const ptr; - constant pointer to constant integer
Your first example static char const *const delimit_method_string[] declares:
static array of constant pointers to constant character
BTW I personally prefer to have the first const before the type ie:
static const volatile char *const delimit_method_string[]
const char *p
What's the difference between:
char * const
and
const char *
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).
There is also a
const char * const
which is a constant pointer to a constant char (so nothing about it can be changed).
Note:
The following two forms are equivalent:
const char *
and
char const *
The exact reason for this is described in the C++ standard, but it's important to note and avoid the confusion. I know several coding standards that prefer:
char const
over
const char
(with or without pointer) so that the placement of the const element is the same as with a pointer const.
To avoid confusion, always append the const qualifier.
int * mutable_pointer_to_mutable_int;
int const * mutable_pointer_to_constant_int;
int *const constant_pointer_to_mutable_int;
int const *const constant_pointer_to_constant_int;
const always modifies the thing that comes before it (to the left of it), EXCEPT when it's the first thing in a type declaration, where it modifies the thing that comes after it (to the right of it).
So these two are the same:
int const *i1;
const int *i2;
they define pointers to a const int. You can change where i1 and i2 points, but you can't change the value they point at.
This:
int *const i3 = (int*) 0x12345678;
defines a const pointer to an integer and initializes it to point at memory location 12345678. You can change the int value at address 12345678, but you can't change the address that i3 points to.
const char* is a pointer to a constant character
char* const is a constant pointer to a character
const char* const is a constant pointer to a constant character
const * char is invalid C code and is meaningless. Perhaps you meant to ask the difference between a const char * and a char const *, or possibly the difference between a const char * and a char * const?
See also:
What are const pointers (as opposed to pointers to const objects)?
Const in C
Difference between const declarations in C++
C++ const question
Why can I change the values of a const char* variable?
Rule of thumb: read the definition from right to left!
const int *foo;
Means "foo points (*) to an int that cannot change (const)".
To the programmer this means "I will not change the value of what foo points to".
*foo = 123; or foo[0] = 123; would be invalid.
foo = &bar; is allowed.
int *const foo;
Means "foo cannot change (const) and points (*) to an int".
To the programmer this means "I will not change the memory address that foo refers to".
*foo = 123; or foo[0] = 123; is allowed.
foo = &bar; would be invalid.
const int *const foo;
Means "foo cannot change (const) and points (*) to an int that cannot change (const)".
To the programmer this means "I will not change the value of what foo points to, nor will I change the address that foo refers to".
*foo = 123; or foo[0] = 123; would be invalid.
foo = &bar; would be invalid.
const char* x Here X is basically a character pointer which is pointing to a constant value
char* const x is refer to character pointer which is constant, but the location it is pointing can be change.
const char* const x is combination to 1 and 2, means it is a constant character pointer which is pointing to constant value.
const *char x will cause a compiler error. it can not be declared.
char const * x is equal to point 1.
the rule of thumb is if const is with var name then the pointer will be constant but the pointing location can be changed , else pointer will point to a constant location and pointer can point to another location but the pointing location content can not be change.
Another thumb rule is to check where const is:
before * => value stored is constant
after * => pointer itself is constant
First one is a syntax error. Maybe you meant the difference between
const char * mychar
and
char * const mychar
In that case, the first one is a pointer to data that can't change, and the second one is a pointer that will always point to the same address.
Lots of answer provide specific techniques, rule of thumbs etc to understand this particular instance of variable declaration. But there is a generic technique of understand any declaration:
Clockwise/Spiral Rule
A)
const char *a;
As per the clockwise/spiral rule a is pointer to character that is constant. Which means character is constant but the pointer can change. i.e. a = "other string"; is fine but a[2] = 'c'; will fail to compile
B)
char * const a;
As per the rule, a is const pointer to a character. i.e. You can do a[2] = 'c'; but you cannot do a = "other string";
Here is a detailed explanation with code
/*const char * p;
char * const p;
const char * const p;*/ // these are the three conditions,
// const char *p;const char * const p; pointer value cannot be changed
// char * const p; pointer address cannot be changed
// const char * const p; both cannot be changed.
#include<stdio.h>
/*int main()
{
const char * p; // value cannot be changed
char z;
//*p = 'c'; // this will not work
p = &z;
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
char * const p; // address cannot be changed
char z;
*p = 'c';
//p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
const char * const p; // both address and value cannot be changed
char z;
*p = 'c'; // this will not work
p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
char * const and const char *?
Pointing to a constant value
const char * p; // value cannot be changed
Constant pointer to a value
char * const p; // address cannot be changed
Constant pointer to a constant value
const char * const p; // both cannot be changed.
I presume you mean const char * and char * const .
The first, const char *, is a pointer to a constant character. The pointer itself is mutable.
The second, char * const is a constant pointer to a character. The pointer cannot change, the character it points to can.
And then there is const char * const where the pointer and character cannot change.
// Some more complex constant variable/pointer declaration.
// Observing cases when we get error and warning would help
// understanding it better.
int main(void)
{
char ca1[10]= "aaaa"; // char array 1
char ca2[10]= "bbbb"; // char array 2
char *pca1= ca1;
char *pca2= ca2;
char const *ccs= pca1;
char * const csc= pca2;
ccs[1]='m'; // Bad - error: assignment of read-only location ‘*(ccs + 1u)’
ccs= csc; // Good
csc[1]='n'; // Good
csc= ccs; // Bad - error: assignment of read-only variable ‘csc’
char const **ccss= &ccs; // Good
char const **ccss1= &csc; // Bad - warning: initialization from incompatible pointer type
char * const *cscs= &csc; // Good
char * const *cscs1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc= &pca1; // Good
char ** const cssc1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc2= &csc; // Bad - warning: initialization discards ‘const’
// qualifier from pointer target type
*ccss[1]= 'x'; // Bad - error: assignment of read-only location ‘**(ccss + 8u)’
*ccss= ccs; // Good
*ccss= csc; // Good
ccss= ccss1; // Good
ccss= cscs; // Bad - warning: assignment from incompatible pointer type
*cscs[1]= 'y'; // Good
*cscs= ccs; // Bad - error: assignment of read-only location ‘*cscs’
*cscs= csc; // Bad - error: assignment of read-only location ‘*cscs’
cscs= cscs1; // Good
cscs= cssc; // Good
*cssc[1]= 'z'; // Good
*cssc= ccs; // Bad - warning: assignment discards ‘const’
// qualifier from pointer target type
*cssc= csc; // Good
*cssc= pca2; // Good
cssc= ccss; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cscs; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cssc1; // Bad - error: assignment of read-only variable ‘cssc’
}
Constant pointer: A constant pointer can point only to a single variable of the respective data type during the entire program.we can change the value of the variable pointed by the pointer. Initialization should be done during the time of declaration itself.
Syntax:
datatype *const var;
char *const comes under this case.
/*program to illustrate the behaviour of constant pointer */
#include<stdio.h>
int main(){
int a=10;
int *const ptr=&a;
*ptr=100;/* we can change the value of object but we cannot point it to another variable.suppose another variable int b=20; and ptr=&b; gives you error*/
printf("%d",*ptr);
return 0;
}
Pointer to a const value: In this a pointer can point any number of variables of the respective type but we cannot change the value of the object pointed by the pointer at that specific time.
Syntax:
const datatype *varor datatype const *var
const char* comes under this case.
/* program to illustrate the behavior of pointer to a constant*/
#include<stdio.h>
int main(){
int a=10,b=20;
int const *ptr=&a;
printf("%d\n",*ptr);
/* *ptr=100 is not possible i.e we cannot change the value of the object pointed by the pointer*/
ptr=&b;
printf("%d",*ptr);
/*we can point it to another object*/
return 0;
}
The const modifier is applied to the term immediately to its left. The only exception to this is when there is nothing to its left, then it applies to what is immediately on its right.
These are all equivalent ways of saying "constant pointer to a constant char":
const char * const
const char const *
char const * const
char const const *
Two rules
If const is between char and *, it will affect the left one.
If const is not between char and *, it will affect the nearest one.
e.g.
char const *. This is a pointer points to a constant char.
char * const. This is a constant pointer points to a char.
I would like to point out that using int const * (or const int *) isn't about a pointer pointing to a const int variable, but that this variable is const for this specific pointer.
For example:
int var = 10;
int const * _p = &var;
The code above compiles perfectly fine. _p points to a const variable, although var itself isn't constant.
I remember from Czech book about C: read the declaration that you start with the variable and go left.
So for
char * const a;
you can read as: "a is variable of type constant pointer to char",
char const * a;
you can read as: "a is a pointer to constant variable of type char. I hope this helps.
Bonus:
const char * const a;
You will read as a is constant pointer to constant variable of type char.
What's the difference between:
char * const
and
const char *
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).
There is also a
const char * const
which is a constant pointer to a constant char (so nothing about it can be changed).
Note:
The following two forms are equivalent:
const char *
and
char const *
The exact reason for this is described in the C++ standard, but it's important to note and avoid the confusion. I know several coding standards that prefer:
char const
over
const char
(with or without pointer) so that the placement of the const element is the same as with a pointer const.
To avoid confusion, always append the const qualifier.
int * mutable_pointer_to_mutable_int;
int const * mutable_pointer_to_constant_int;
int *const constant_pointer_to_mutable_int;
int const *const constant_pointer_to_constant_int;
const always modifies the thing that comes before it (to the left of it), EXCEPT when it's the first thing in a type declaration, where it modifies the thing that comes after it (to the right of it).
So these two are the same:
int const *i1;
const int *i2;
they define pointers to a const int. You can change where i1 and i2 points, but you can't change the value they point at.
This:
int *const i3 = (int*) 0x12345678;
defines a const pointer to an integer and initializes it to point at memory location 12345678. You can change the int value at address 12345678, but you can't change the address that i3 points to.
const char* is a pointer to a constant character
char* const is a constant pointer to a character
const char* const is a constant pointer to a constant character
const * char is invalid C code and is meaningless. Perhaps you meant to ask the difference between a const char * and a char const *, or possibly the difference between a const char * and a char * const?
See also:
What are const pointers (as opposed to pointers to const objects)?
Const in C
Difference between const declarations in C++
C++ const question
Why can I change the values of a const char* variable?
Rule of thumb: read the definition from right to left!
const int *foo;
Means "foo points (*) to an int that cannot change (const)".
To the programmer this means "I will not change the value of what foo points to".
*foo = 123; or foo[0] = 123; would be invalid.
foo = &bar; is allowed.
int *const foo;
Means "foo cannot change (const) and points (*) to an int".
To the programmer this means "I will not change the memory address that foo refers to".
*foo = 123; or foo[0] = 123; is allowed.
foo = &bar; would be invalid.
const int *const foo;
Means "foo cannot change (const) and points (*) to an int that cannot change (const)".
To the programmer this means "I will not change the value of what foo points to, nor will I change the address that foo refers to".
*foo = 123; or foo[0] = 123; would be invalid.
foo = &bar; would be invalid.
const char* x Here X is basically a character pointer which is pointing to a constant value
char* const x is refer to character pointer which is constant, but the location it is pointing can be change.
const char* const x is combination to 1 and 2, means it is a constant character pointer which is pointing to constant value.
const *char x will cause a compiler error. it can not be declared.
char const * x is equal to point 1.
the rule of thumb is if const is with var name then the pointer will be constant but the pointing location can be changed , else pointer will point to a constant location and pointer can point to another location but the pointing location content can not be change.
Another thumb rule is to check where const is:
before * => value stored is constant
after * => pointer itself is constant
First one is a syntax error. Maybe you meant the difference between
const char * mychar
and
char * const mychar
In that case, the first one is a pointer to data that can't change, and the second one is a pointer that will always point to the same address.
Lots of answer provide specific techniques, rule of thumbs etc to understand this particular instance of variable declaration. But there is a generic technique of understand any declaration:
Clockwise/Spiral Rule
A)
const char *a;
As per the clockwise/spiral rule a is pointer to character that is constant. Which means character is constant but the pointer can change. i.e. a = "other string"; is fine but a[2] = 'c'; will fail to compile
B)
char * const a;
As per the rule, a is const pointer to a character. i.e. You can do a[2] = 'c'; but you cannot do a = "other string";
Here is a detailed explanation with code
/*const char * p;
char * const p;
const char * const p;*/ // these are the three conditions,
// const char *p;const char * const p; pointer value cannot be changed
// char * const p; pointer address cannot be changed
// const char * const p; both cannot be changed.
#include<stdio.h>
/*int main()
{
const char * p; // value cannot be changed
char z;
//*p = 'c'; // this will not work
p = &z;
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
char * const p; // address cannot be changed
char z;
*p = 'c';
//p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
/*int main()
{
const char * const p; // both address and value cannot be changed
char z;
*p = 'c'; // this will not work
p = &z; // this will not work
printf(" %c\n",*p);
return 0;
}*/
char * const and const char *?
Pointing to a constant value
const char * p; // value cannot be changed
Constant pointer to a value
char * const p; // address cannot be changed
Constant pointer to a constant value
const char * const p; // both cannot be changed.
I presume you mean const char * and char * const .
The first, const char *, is a pointer to a constant character. The pointer itself is mutable.
The second, char * const is a constant pointer to a character. The pointer cannot change, the character it points to can.
And then there is const char * const where the pointer and character cannot change.
// Some more complex constant variable/pointer declaration.
// Observing cases when we get error and warning would help
// understanding it better.
int main(void)
{
char ca1[10]= "aaaa"; // char array 1
char ca2[10]= "bbbb"; // char array 2
char *pca1= ca1;
char *pca2= ca2;
char const *ccs= pca1;
char * const csc= pca2;
ccs[1]='m'; // Bad - error: assignment of read-only location ‘*(ccs + 1u)’
ccs= csc; // Good
csc[1]='n'; // Good
csc= ccs; // Bad - error: assignment of read-only variable ‘csc’
char const **ccss= &ccs; // Good
char const **ccss1= &csc; // Bad - warning: initialization from incompatible pointer type
char * const *cscs= &csc; // Good
char * const *cscs1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc= &pca1; // Good
char ** const cssc1= &ccs; // Bad - warning: initialization from incompatible pointer type
char ** const cssc2= &csc; // Bad - warning: initialization discards ‘const’
// qualifier from pointer target type
*ccss[1]= 'x'; // Bad - error: assignment of read-only location ‘**(ccss + 8u)’
*ccss= ccs; // Good
*ccss= csc; // Good
ccss= ccss1; // Good
ccss= cscs; // Bad - warning: assignment from incompatible pointer type
*cscs[1]= 'y'; // Good
*cscs= ccs; // Bad - error: assignment of read-only location ‘*cscs’
*cscs= csc; // Bad - error: assignment of read-only location ‘*cscs’
cscs= cscs1; // Good
cscs= cssc; // Good
*cssc[1]= 'z'; // Good
*cssc= ccs; // Bad - warning: assignment discards ‘const’
// qualifier from pointer target type
*cssc= csc; // Good
*cssc= pca2; // Good
cssc= ccss; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cscs; // Bad - error: assignment of read-only variable ‘cssc’
cssc= cssc1; // Bad - error: assignment of read-only variable ‘cssc’
}
Constant pointer: A constant pointer can point only to a single variable of the respective data type during the entire program.we can change the value of the variable pointed by the pointer. Initialization should be done during the time of declaration itself.
Syntax:
datatype *const var;
char *const comes under this case.
/*program to illustrate the behaviour of constant pointer */
#include<stdio.h>
int main(){
int a=10;
int *const ptr=&a;
*ptr=100;/* we can change the value of object but we cannot point it to another variable.suppose another variable int b=20; and ptr=&b; gives you error*/
printf("%d",*ptr);
return 0;
}
Pointer to a const value: In this a pointer can point any number of variables of the respective type but we cannot change the value of the object pointed by the pointer at that specific time.
Syntax:
const datatype *varor datatype const *var
const char* comes under this case.
/* program to illustrate the behavior of pointer to a constant*/
#include<stdio.h>
int main(){
int a=10,b=20;
int const *ptr=&a;
printf("%d\n",*ptr);
/* *ptr=100 is not possible i.e we cannot change the value of the object pointed by the pointer*/
ptr=&b;
printf("%d",*ptr);
/*we can point it to another object*/
return 0;
}
The const modifier is applied to the term immediately to its left. The only exception to this is when there is nothing to its left, then it applies to what is immediately on its right.
These are all equivalent ways of saying "constant pointer to a constant char":
const char * const
const char const *
char const * const
char const const *
Two rules
If const is between char and *, it will affect the left one.
If const is not between char and *, it will affect the nearest one.
e.g.
char const *. This is a pointer points to a constant char.
char * const. This is a constant pointer points to a char.
I would like to point out that using int const * (or const int *) isn't about a pointer pointing to a const int variable, but that this variable is const for this specific pointer.
For example:
int var = 10;
int const * _p = &var;
The code above compiles perfectly fine. _p points to a const variable, although var itself isn't constant.
I remember from Czech book about C: read the declaration that you start with the variable and go left.
So for
char * const a;
you can read as: "a is variable of type constant pointer to char",
char const * a;
you can read as: "a is a pointer to constant variable of type char. I hope this helps.
Bonus:
const char * const a;
You will read as a is constant pointer to constant variable of type char.
This question already has answers here:
What is the difference between char * const and const char *?
(19 answers)
Closed 7 years ago.
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?
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.
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;.
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.
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
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:
nothing is const
the pointer is const
the object pointed to is const
both the pointer and the pointed to object are const.
These different possibilities can be expressed in C as follows:
char * a;
char * const a;
const char * a;
const char * const a;
I hope this illustrates the possible differences
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. */
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):
A 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.
A 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!
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;)
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
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!.
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!!! :)
Using V1.8 z/OS XL C compiler, with warnings jacked-up using INFO(ALL), I get the following warning on line 4 of the code below:
WARNING CCN3196 Initialization between types "const int** const" and "int**"
is not allowed.
1 int foo = 0;
2 int *ptr = &foo;
3 const int * const fixed_readonly_ptr = ptr;
4 const int ** const fixed_ptr_to_readonly_ptr = &ptr;
I can't wrap my head around why I'm getting this warning. If I can assign an int pointer to a const pointer to const int (line 3), then why can't I assign the address of an int pointer to a const pointer to pointer to const int? What am I missing?
Note the code above is a slimmed down example just showing the issue I'm encountering in a small amount of code. The real context is that I have a const pointer to pointer to struct (struct s** const) and am passing it as an argument to a function who's parameter is defined as a const pointer to pointer to const struct (const struct s** const). This is because the function will not modify the data in the struct (hence the first const) and it does not modify the pointer parameter which always holds the address passed in (hence the second const). The value of the pointer pointed to may be changed by the way (which is why there is NOT a third const in between the **).
It's a type safety violation. Consider this code (I shuffled const around a bit to make it clear whether it applies to pointer or pointee, but semantically it means exact same thing):
int* p = 0;
int const** pp = &p; // presumably ok
int const c = 123;
*pp = &c; // okay, &c is int const*, and *p is int const* lvalue
*p = 666; // okay, *p is int lvalue
// wait, so we just changed the value of (const) c above, with no const_cast!
The C rule is that you can convert a pointer to something to a pointer to const something, but that something has to be exactly the same type including const and volatile qualifications further down the chain.
The rationale for this rule is that if the second of these two lines were allowed:
int *ptr;
const int ** const fixed_ptr_to_readonly_ptr = &ptr;
then this can be used to break type safety without a cast.
const int i = 4;
// OK, both sides have type const int *
*fixed_ptr_to_readonly_ptr = &i;
// the value of fixed_ptr_to_readonly_ptr is still &ptr
// the value of ptr is now &i;
*ptr = 5;
// oops, attempt to change the value of i which is const
This is a type-safety violation. You probably want to use a const int * const * instead.
See http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17