When I compile the program below with GCC 4.9.2 I get the following warning: passing argument 1 of ‘P’ from incompatible pointer type. However, I don't see anything wrong with the program. Any clues?
typedef int Row[10];
void P(const Row A[])
{
}
int main(void)
{
Row A[10];
P(A);
return 0;
}
Here is the complete output from GCC to stderr:
test.c: In function ‘main’:
test.c:12:4: warning: passing argument 1 of ‘P’ from incompatible pointer type
P(A);
^
test.c:3:6: note: expected ‘const int (*)[10]’ but argument is of type ‘int (*)[10]’
void P(const Row A[])
^
Edit: The program compiles cleanly with Clang 3.5.0 and the options -pedantic -std=c89 -Wall
.
Get rid of the typedef and it should become a little bit clearer:
void P (const int A [][10])
{
}
int main(void)
{
int A[10][10];
P(A);
return 0;
}
The problem is that the array in the function parameter "decays" into a pointer of type const int(*) [10]
, which is a pointer to an array where the items are const
.
This pointer type is not compatible with what you pass from main, because that array decays into an array pointer of type int(*)[10]
.
There is a rule of "pointer-to-type may be converted to qualified-pointer-to-type". Meaning for example int*
may be converted to const int*
but not the other way around. But that rule does not apply here.
Because the qualified version of "pointer-to-array" is "const-pointer-to-array", and not "pointer-to-const-array", which is what you have here.
Unfortunately this is a weakness in the C language: you cannot have const correctness while using array pointers. The only solution is a very ugly one:
P( (const int(*)[10]) A);
It might be better to skip const correctness completely for cases like this, in favour of readability.
Edit: In C11 you can do like this, which is more type safe but it still relies on the caller performing a cast:
#define const_array_cast(arr, n) _Generic(arr, int(*)[n] : (const int(*)[n])arr )
void P (const int A [][10])
{
}
int main(void)
{
int A[10][10];
P(const_array_cast(A,10));
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With