6

Possible Duplicate:
why isnt it legal to convert (pointer to pointer to non-const) to a (pointer to pointer to a const)

Hi I have the following code, but cannot wrap my head around why this doesn't work - I get an error saying "cannot convert from int** to const int**". However, if I change the first argument of printValues to be "const int *const * myArray", it all works fine. I know I probably shouldn't be using the one below anyway, but I don't understand why it doesn't compile at all. Can you not have a pointer to a pointer to a constant integer without declaring it constant in main()?

#include <iostream> int printValues(const int ** myArray, const long nRows, const long nCols) { for (long iRow = 0; iRow < nRows; iRow++) { for (long iCol = 0; iCol < nCols; iCol++) { std::cout << myArray[iRow][iCol] << " "; } std::cout << "\n"; } return 0; } int main() { const long nRows = 5; const long nCols = 8; int** myArray = new int* [nRows]; for (long iRow = 0; iRow < nRows; iRow++) { myArray[iRow] = new int [nCols]; } for (long iRow = 0; iRow < nRows; iRow++) { for (long iCol = 0; iCol < nCols; iCol++) { myArray[iRow][iCol] = 1; } } printValues(myArray, nRows, nCols); return 0; } 
3

3 Answers 3

7
  • int ** is: "a pointer to a pointer to an integer".
  • const int ** is: "a pointer to a pointer to a constant integer".

A far-fetched analogy:

  • a note that describes the location of another note that describes the location of a jar
  • a note that describes the location of another note that describes the location of a closed jar

You can only put a cookie inside a jar that is not closed.

Now, think of replacing the second note with a photocopy of the first note. Do you have any guarantee that the ultimate jar that this note points to will be closed and cannot accept any cookies? The use of const is a contract and you cannot meet this contract by going through the indirection of two references.

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

3 Comments

Its better to explain this by code, than by jar and cookie. jar and cookie are not C++ semantics, and so it would be very difficult to see the flaw if there is any in the analogy.
@Nawaz: Most people find it hard to wrap their minds around pointers, so I thought a tangible example would be helpful. I kinda left it to other answerers to present it in code terms...
Cookies are certainly more delicious than pointers.
1

Basically, this is because it's possible via changing the level of indirection and other valid, non-const-violating semantics that you can work around the const if it's only on the top level. You have to add const on more than one level for the const to be actually safe.

Comments

1

Edit:

You are violating const-correctness. By saying you want a pointer-to-a-pointer, you are setting yourself up by allowing the original const object to be modified. Const is a contract. By allowing this to happen without a cast, you are setting yourself up to allow a const object to be modified later on.

6 Comments

You can always convert non-const to const. Read @James McNellis' link for why this specific scenario converts const to non-const.
(in reference to 0A0D's comment) That's also true if I change the function argument to "const int *const * myArray" though, isn't it? And it compiles happily if I do that
@0A0D: I don't know what you mean by that. You can do void something(int* foo) { const int bar = *foo; } all day long.
@Billy: The double-pointer is key.
@0A0D: I still don't see your point. Your answer says "passing a non-const integer that can be changed later and that is against the rules" -- huh? Obviously you can change a non-const integer. Your answer also says "you must define it initially as const", which is also false. You can create a constant pointer pointing to non constant data.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.