Discussion:
Cannot convert ‘int [][]’ to ‘int**’ in assignment
(too old to reply)
kiran
2012-09-25 20:14:54 UTC
Permalink
Here is a code snippet:
=============
int **ptr;
int intArr[3][5];
ptr = intArr;
=============

This gives the error on g++ compiler:
error: cannot convert ‘int [3][5]’ to ‘int**’ in assignment

I have tried other variants as well, like
int const **ptr = intArr;
and
ptr = &intArr[0];

I still got the same error. Can anyone explain the reason here.

Thanks,
Kiran
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Daniel Krügler
2012-09-25 20:46:53 UTC
Permalink
Post by kiran
=============
int **ptr;
int intArr[3][5];
ptr = intArr;
=============
error: cannot convert ‘int [3][5]’ to ‘int**’ in assignment
I have tried other variants as well, like
int const **ptr = intArr;
and
ptr = &intArr[0];
I still got the same error. Can anyone explain the reason here.
The reason for this is, because array-to-pointer conversion does not
have an arbitrary depth. The relevant wording in 4.2 [conv.array] p1 is:

"An lvalue or rvalue of type “array of N T” or “array of unknown bound
of T” can be converted to a prvalue of type “pointer to T”. The result
is a pointer to the first element of the array."

Applied to your example we have intArr, which has type "array of 3 array
of 5 int". The quoted wording says that this type can undergo an
array-to-pointer conversion to type "pointer to array of 5 int", which
can be written as the type int (*)[5]. Note that at this point we have
no longer an array anymore, therefore no further decay to int** is possible.

HTH & Greetings from Bremen,

Daniel Krügler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Seungbeom Kim
2012-09-26 04:15:22 UTC
Permalink
Post by kiran
=============
int **ptr;
int intArr[3][5];
ptr = intArr;
=============
error: cannot convert ‘int [3][5]’ to ‘int**’ in assignment
I have tried other variants as well, like
int const **ptr = intArr;
and
ptr = &intArr[0];
I still got the same error. Can anyone explain the reason here.
Please see Question 6.18 from comp.lang.c FAQ <http://www.c-faq.com/>;
though you're assigning the array to a variable instead of passing it
to a function, the same principle applies.
--
Seungbeom Kim


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Wil Evers
2012-09-26 05:04:13 UTC
Permalink
Post by kiran
=============
int **ptr;
int intArr[3][5];
ptr = intArr;
=============
error: cannot convert ‘int [3][5]’ to ‘int**’ in assignment
I have tried other variants as well, like
int const **ptr = intArr;
and
ptr = &intArr[0];
I still got the same error. Can anyone explain the reason here.
The declaration

int intArr[3][5];

declares intArr to be an array of 3 arrays of 5 ints. The language's
decay rule says that the name of this array can be implictly converted
to a pointer to its first element. Thus, we can write:

int (*p1)[5] = intArr;

Note that p1 is not a pointer to a pointer to an int; it is a pointer to
an array of 5 ints, pointing to intArr[0].

In contrast, if we write:

int **p2;

We're saying that p2 points to a pointer to an int. If it were legal to
write

int **p2 = intArr;

then where is the pointer that p2 points to? There is none, which is
why this conversion has to be illegal.

HTH,

- Wil
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Francis Glassborow
2012-09-26 17:43:19 UTC
Permalink
Post by kiran
=============
int **ptr;
int intArr[3][5];
ptr = intArr;
=============
error: cannot convert ‘int [3][5]’ to ‘int**’ in assignment
I have tried other variants as well, like
int const **ptr = intArr;
and
ptr = &intArr[0];
I still got the same error. Can anyone explain the reason here.
Thanks,
Kiran
Others have given you the explanation as to why it fails but you may be
interested in why the language works this way.

Ritchie when designing C wanted to ensure that arrays could be
effectively passed to functions and that you did not need a different
function for different size arrays (which would have been very
cumbersome in a language that did not support overloading). C++ can
sidestep this problem by using templates but also maintains backward
compatibility with C.

One of the consequences of Ritchie's design decision was that C only
support one dimensional arrays, likewise C++ (though advanced library
designers manage multiple dimensions). In addition pointer arithmetic
becomes essential (because a function only gets a pointer to an array)
and for this to work the compiler must be able to work out the size of
the element of the array.

Given the above, how would you use a T** if it were the address of an
array of arrays? You would have no way (unless we required arrays to
know their own size as we do for vectors) to compute the addresses of
the elements beyond the first row.

Note that C++ std::vector avoids these constraints because vectors store
their current size.

Francis
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Loading...