In some c code I inherited, I have seen the following
int (*b)[] = (int(*)[])a;
What is int(*)[] and how is this different than int**?
In some c code I inherited, I have seen the following
int (*b)[] = (int(*)[])a;
What is int(*)[] and how is this different than int**?
As per The ``Clockwise/Spiral Rule'',
int(*)[]
is a pointer to an array of int.
int(*)[] int[]
+---------+ +---------+
| ------->| |
+---------+ +---------+
: :
int**
is a pointer to a pointer to an int.
int** int* int
+---------+ +---------+ +---------+
| ------->| ------->| |
+---------+ +---------+ +---------+
:? :? :? :?
As you can see, int(*)[]
is closer to int*
than to int**
.
int* int
+---------+ +---------+
| ------->| |
+---------+ +---------+
:? :?
All of these have distinctively different meanings:
int*
= pointer to int
int[]
= array of int, with incomplete type since the size is missing.int**
= pointer to pointer to int
.int(*)[]
= pointer to (incomplete) array of intNotably an int**
, pointer to pointer to int
, cannot be assigned to point at an array, nor to an array of arrays. It has nothing to do with arrays! With one special exception: it can be assigned to point at the first element in an array of int*
, that is an array of type int* arr[]
. We may then write int** ptr = arr;
in that special case and only then.
Most of the misconception regarding int**
originates from the misconception that int**
together with malloc could be used to allocate a 2D array, which was never the case, see Correctly allocating multi-dimensional arrays.
Regarding int(*)[]
it's a handy type in some cases, since an array with no size (incomplete type) is compatible with an array of fixed size (through a special rule called "composite type"). So we can use a int(*)[]
to point at any int
array type no matter size. Or use it to create a macro to check if something is an array: #define IS_INT_ARRAY(x) _Generic(&(x), int(*)[]: puts(#x " is an int array"))