2
int x = 10;
int * const p = &x;
const int **p1 = &p;

Having some trouble understanding why this is illegal.

EDIT

Thank you for all the great answers. Here is my interpretation of the answers, feel free to disagree. So, the error is in the 3rd line. It implies that original integer is constant but does not imply that the pointer it points to is constant and therefore it is illegal because we could attempt to change the pointer 'p' through 'p1' which is not possible because that is a constant pointer. So to fix this the third line must be:

int * const *p1 = &p;

This works because it says that while the original integer is non-constant (mutable) the pointer it points to is constant and therefore it is a legal statement. So this is also legal:

const int * const *p1 = &p;

This says the same thing except it also says that you cant change the original integer because it is constant.

6
  • 3
    What's your intent with int * const p? Commented Jun 5, 2018 at 19:10
  • 1
    when there is a error message you should include it in the question, usually they already give a hint on what is wrong Commented Jun 5, 2018 at 19:12
  • @VTT You've explained it correctly. That notation is really unusual, which is why I got confused. Commented Jun 5, 2018 at 19:13
  • @vtt A neat tool, but in this case probably just needed to pay closer attention to the declaration. Commented Jun 5, 2018 at 19:17
  • this might help: cdecl.org Commented Jun 5, 2018 at 19:22

5 Answers 5

5

Something you need to get used to with pointer declarations is that you need to try reading them right to left. What matters is what's on each side of the *

int * const p means p is a const pointer to a non-const int

const int **p1 means p1 is a non-const pointer to a non-const pointer to a const int

Your second declaration fails because it creates a non-const variable from a const one.

Sign up to request clarification or add additional context in comments.

4 Comments

almost correct, according to your last sentence this shouldnt work: const int x = 3; int y = x;
I understand what you're saying but even this does not work and seems to follow that logic:const int ci = 42; const int * const p3 = &ci; const int ** p = &p3;
At the top level, it's a copy, so the const doesn't matter. Const that is "wrapped inside" a pointer or reference sticks. Taking the address of something const cannot be assigned to something that holds the address of something non-const, or you could end up changing the const value through just by looking at it through the non-const lens (without a cast.)
@ChrisUzdavinis yes, thank you for clarifying where I failed to elaborate
2

Initializes new mutable int x with literal 10, fine:

int x = 10;

Initializes new constant pointer to mutable int p with address of x, fine:

int * const p = &x;

Initializes new mutable pointer to mutable pointer to constant int with address of p, constraint violation due to stripping the const, and also due to adding the inner-most const:

const int **p1 = &p;
// Normally qualifiers go to the right of the type they qualify
// The inner-most qualifiers can be put before them though without introducing ambiguity

Read the full rules on cppreference.com or directly in the standard, they are a bit long.

2 Comments

"and also due to adding the inner-most const" adding const should not be a problem, removing is
@Slava It can be, and in this case it is a problem. See the link for the nitty-gritty.
1

Declares 2 ints which are constant:

int const x1 = 3;
const int x2 = 3;

Declares a pointer whose data cannot be changed through the pointer:

const int *p = &someInt;

Declares a pointer who cannot be changed to point to something else:

int * const p = &someInt;

Link: const int = int const?

Comments

0

The compiler (here, gcc) tells you

invalid conversion from 'int* const*' to 'const int**' [-fpermissive]

And the reason is that

p1 is a pointer to (non-const) pointer to const int

while

p is a const pointer to int

If the assignment was legal, you could modify the const variable p through p1 (as the type of *p1 would be const int * -- pointer to const int).

Comments

0

In

int * const p = &x;

that means the address/reference is constant, since the const comes after * (as opposed to the target value being constant, in other words const before the *, in other words const int *p)

In

const int **p1 = &p;

that means, p1, which I'll call the "outer pointer" points to const int *, which is wrong, b.c. it should be pointing to an int *const as the previous expression states.

In other words, as the compiler puts it,

error: cannot initialize a variable of type 'const int **' with an rvalue of type 'int *const *'
const int **p1 = &p;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.