Each One Chew
Each One Chew

Reputation: 179

C type notation

I've always been slightly confused as to how C type notation works. I don't have access to Google, and Bing is turning up garbage results.

For example: what does int *(*)[] mean? I know already that it's a pointer to an array of integer pointers (I think), but why? In particular, I'm confused as to what the brackets are doing; yeah, int **[] would be an array of pointers to pointers, but why does () change that?

Upvotes: 4

Views: 382

Answers (1)

To read such types, mentally add a variable name to the expression to turn it into a valid declaration. Then read it from the inside out, like you read all variable declarations in C:

int **[]   ->   int **a[];

a[]         //[] has higher precedence than *, so `a` is an array
*a[]        //this array contains pointers
**a[]       //which dereference to pointers
int **a[];  //which dereference to int

So, int**[] is the type of an array of pointers to pointers to int.

With the other type, we get:

int *(*)[]   ->   int *(*a)[];

*a            //a is a pointer
(*a)          //(precedence control, only)
(*a)[]        //which dereferences to an array
*(*a)[]       //which contains pointers
int *(*a)[];  //which dereference to int

So, int*(*)[] is the type of a pointer to an array of pointers to int.

As you see, the parentheses have the effect of selecting the first * operator before the []. The later has higher precedence, so if you need a pointer to an array, you need to introduce the parentheses.


There are three operators which are relevant to type declarations, and it's important to know their precedence:

High precedence:
[]    array subscript declares an array
()    function call declares a function

Low precedence:
*     dereference operator declares a pointer

Because the * has lower precedence than either () or [], you need to add the extra parentheses to declare pointers to arrays or functions:

int *a[];    //array of pointers, as a cast: `(int*[])`
int (*a)[];  //pointer to an array, as a cast: `(int(*)[])`

int *a();    //function returning a pointer, as a cast: `(int*())`
int (*a)(); //pointer to a function returning an `int`, as a cast: `(int(*)())`

Once you've understood this principle, no type expression in C will confound you anymore.

Upvotes: 6

Related Questions