August Karlstrom <
fusio...@gmail.com> writes:
> My question is whether this is a valid ANSI C (C89) program or not:
>
> typedef int Row[10];
>
> void P(const Row A[])
The [] might confuse some people. This is simply
void P(const Row *A)
> {
> }
>
> int main(void)
> {
> Row A[10];
>
> P(A);
> return 0;
> }
>
> It compiles cleanly with Clang 3.5.0 and the options -pedantic
> -std=c89 -Wall.
>
> GCC 4.9.2, however, is not happy:
>
> $ gcc -c -o test.o -g -pedantic -std=c89 -Wall test.c
> 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[])
> ^
>
> Any clues?
I think gcc is right to complain.
Whilst the types are not compatible, that's not really the problem here.
For example, you can pass an int * to a function that takes const int *
and those two types are not compatible. Argument passing is done "as if
by assignment", and in an assignment the pointed-to type on the left can
have extra qualifiers. But here, the const qualifies the element type,
not the pointed-to type, which is an array type. (C has not qualified
array types at all).
The call is safe, of course, but C chose to use a simple rule rather
than trying to identify only those calls (and assignments) that are not
safe. C++ has a more comprehensive rule.
Cases like this (and passing to a const T ** parameter) are some of the
rare times when you really need a cast.
--
Ben.