I was going through the answers to this question Why is it allowed to omit the first dimension, but not the other dimensions when declaring a multi-dimensonal array? and some other questions as well and I understood that we can omit the first dimension but other dimensions are inevitable to be specified.
To my surprise, the following code executed perfectly fine:
#include<stdio.h>
void f1(int (*p)[]){
//SOMETHING
}
int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
f1(a);
}
However, if I use the pointer p to print some value like
printf("%d",p[0][1]);
It gives an error message saying:
error: invalid use of array with unspecified bounds
Why does C allow such kind of declaration?
If it is very certain that it is going to throw an error on pointer's use then why is it not throwing error at the time of declaration itself? Why wait for pointer's use to throw an error?
Is there any specific reason for allowing such a declaration?
The expression
p[0][1]containsp[0].p[0]is defined to be equivalent to*(p+0). This uses the addition of a pointer and an integer.There is a rule that addition with a pointer requires a pointer to a complete object type. This is because calculating how many bytes the address must be changed by usually requires knowing the size of the objects being pointed to. It does not when adding zero, but there is no exception in the rule for this.
The type of
pis “pointer to array of unknown number ofint. Because the number of elements in the array is unknown, the type is incomplete. So the addition is not allowed.Interestingly,
(*p)[1]is allowed, even though it refers to the same thingp[0][1]would. It is allowed because calculating*pdoes not require pointer addition.ppoints to an array, so we know where that array starts even though we do not know its size.The need to know object size for pointer arithmetic is why the elements of an array must have a complete type (so, if those elements are themselves arrays, their length must be given, to make them complete, and so all inner dimensions of arrays must be known). But pointers are allowed to point to incomplete types, so, when a pointer points to an array, it is not required that the array dimension be known.