Reputation: 258548
From my understanding, const
modifiers should be read from right to left. From that, I get that:
const char*
is a pointer whose char elements can't be modified, but the pointer itself can, and
char const*
is a constant pointer to mutable
chars.
But I get the following errors for the following code:
const char* x = new char[20];
x = new char[30]; //this works, as expected
x[0] = 'a'; //gives an error as expected
char const* y = new char[20];
y = new char[20]; //this works, although the pointer should be const (right?)
y[0] = 'a'; //this doesn't although I expect it to work
So... which one is it? Is my understanding or my compiler(VS 2005) wrong?
Upvotes: 84
Views: 40587
Reputation: 41
In both of your cases you're pointing to a constant char.
const char * x //(1) a variable pointer to a constant char
char const * x //(2) a variable pointer to a constant char
char * const x //(3) a constant pointer to a variable char
char const * const x //(4) a constant pointer to a constant char
char const * const * x //(5) a variable pointer to a constant pointer to a constant char
char const * const * const x //(6) can you guess this one?
By default, const
applies to what is inmediately at is left, but it could apply to what is inmediately at its right if there's nothing preceeding it, as in (1).
Upvotes: 0
Reputation: 39089
(from 2 simple variable initialization question)
A really good rule of thumb regarding const
:
Read Declarations Right-to-Left.
(see Vandevoorde/Josutiss "C++ Templates: The Complete Guide")
E.g.:
int const x; // x is a constant int
const int x; // x is an int which is const
// easy. the rule becomes really useful in the following:
int const * const p; // p is const-pointer to const-int
int const &p; // p is a reference to const-int
int * const * p; // p is a pointer to const-pointer to int.
Ever since I follow this rule-of-thumb, I never misinterpreted such declarations again.
(: sisab retcarahc-rep a no ton ,sisab nekot-rep a no tfel-ot-thgir naem I hguohT :tidE
Upvotes: 13
Reputation: 3678
Actually, according to the standard, const
modifies the element directly to its left. The use of const
at the beginning of a declaration is just a convenient mental shortcut. So the following two statements are equivalent:
char const * pointerToConstantContent1;
const char * pointerToConstantContent2;
In order to ensure the pointer itself is not modified, const
should be placed after the asterisk:
char * const constantPointerToMutableContent;
To protect both the pointer and the content to which it points, use two consts.
char const * const constantPointerToConstantContent;
I've personally adopted always putting the const after the portion I intend not to modify such that I maintain consistency even when the pointer is the part I wish to keep constant.
Upvotes: 135
Reputation: 5177
Here is how I always try to interpret:
char *p
|_____ start from the asterisk. The above declaration is read as: "content of `p` is a `char`".
char * const p
|_____ again start from the asterisk. "content of constant (since we have the `const`
modifier in the front) `p` is a `char`".
char const *p
|_____ again start from the asterisk. "content of `p` is a constant `char`".
Hope it helps!
Upvotes: 5
Reputation: 69968
It works because both are same. May be you confused in this,
const char* // both are same
char const*
and
char* const // unmutable pointer to "char"
and
const char* const // unmutable pointer to "const char"
[To remember this, here is a simple rule, '*' affects its whole LHS first]
Upvotes: 32
Reputation: 1300
That is because the rule is:
RULE: const
binds left, unless there is nothing on the left, then it binds right :)
so, look at these as:
(const --->> char)*
(char <<--- const)*
both same! oh, and --->>
and <<---
are NOT operators, they just show what the const
binds to.
Upvotes: 28