Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: pedantic gcc and const 2D arrays
Date: Wed, 08 Apr 2026 21:42:22 -0700
Organization: A noiseless patient Spider
Lines: 94
Message-ID: <86ldewwxqp.fsf@linuxsc.com>
References: <20260409012107.00006dc5@yahoo.com> <87ldex2h8e.fsf@example.invalid> <20260409030937.00000c95@yahoo.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Date: Thu, 09 Apr 2026 04:42:25 +0000 (UTC)
Injection-Info: dont-email.me; posting-host="58cb476bd973d15d025d3b0e2ffe71fe"; logging-data="94259"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+5pVddXr6qdzV+fd7huI4wZ+lpIWs/jtY="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:l6Jo7mJKeI83knEbU8uEsJAKiDE= sha1:ydW/bZFIZSpSFp7RD6QQ/bd4zXg=
Xref: csiph.com comp.lang.c:397443
Michael S writes:
> On Wed, 08 Apr 2026 15:57:05 -0700
> Keith Thompson wrote:
>
>> Michael S writes:
>>
>>> IIRC, this is my first on-topic post in comp.lang.c group.
>>> As they say, nobody is perfect.
>>>
>>> // pedant_2d.c
>>> int bar(const int a[5][42])
>>> {
>>> return a[0][0];
>>> }
>>>
>>> int foo(int x)
>>> {
>>> int a[5][42];
>>> a[0][0] = 1;
>>> return bar(a);
>>> }
>>>
>>> // end of pedant_2d.c
>>>
>>>
>>> $ gcc -std=c17 -pedantic -c pedant_2d.c
>>> pedant_2d.c: In function 'foo':
>>> pedant_2d.c:10:14: warning: invalid use of pointers to arrays with
>>> different qualifiers in ISO C before C23 [-Wpedantic] 10 | return
>>> bar(a); | ^
>>>
>>> What does it mean ?
>>
>> This is an incomplete answer. Perhaps someone else can fill in
>> some more details.
>>
>> Given the parameter declaration `const int a[5][42]`, a is of
>> course a pointer, not an array. Specifically, it's of type
>> `constint(*)[42])`, or "pointer to array 42 of const int".
>> (The 5 is quietly ignored.)
>>
>> The argument `a` in the call (it might have been clearer to use
>> distinct names) is of type `int[5][42]`, or "array 5 of array
>> 42 of int". In the call, as in most contexts, it decays to
>> `int (*)[42]`, or "pointer to array 42 of int".
>>
>> The problem is that the types "pointer to array N of int" and
>> "pointer to array N of const int" are distinct and are not
>> assignment-compatible.
>
> int bar(const int a[42])
> {
> return a[0];
> }
>
> int foo(int x)
> {
> int a[42];
> a[0] = 1;
> return bar(a);
> }
>
> That, of course, compile with no wraning.
> So, 'pointer to int' is, according to gcc, assignment-compatible (on
> the right side) with 'pointer to const int', but in case of pointers to
> arrays it is not the same?
The analogous case with pointers is not const int * but const int **,
which also fails if given an int **. Andrey Tarasevich gave an
explanation.
> IMHO, if the standard really says that then every reasonable compiler
> shall ignore the Standard and follow practicality.
I think that's an overreaction. This particular problem doesn't come
up very often. When it does, usually it's easy to fix just by writing
a wrapper function and calling that instead:
int bar(const int a[5][42])
{
return a[0][0];
}
int bas(int a[5][42]){
return bar( (const int (*)[42]) a );
}
int foo(int x)
{
int a[5][42];
a[0][0] = 1;
return bas(a);
}