Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #398032
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: pedantic gcc and const 2D arrays |
| Date | 2026-04-27 07:27 -0700 |
| Organization | A noiseless patient Spider |
| Message-ID | <86qzo01nrx.fsf@linuxsc.com> (permalink) |
| References | (3 earlier) <20260409140602.00007b72@yahoo.com> <10r912i$jtv1$1@dont-email.me> <10rgobr$2o806$1@dont-email.me> <864ilf823x.fsf@linuxsc.com> <10sltgu$1s5u8$1@dont-email.me> |
Andrey Tarasevich <noone@noone.net> writes:
> On Mon 4/13/2026 5:40 AM, Tim Rentsch wrote:
>
>> But arrays are another
>> kettle of fish altogether, and I'm happy to see the issues around
>> const arrays are finally getting the attention they deserve (which I
>> have been advocating for more than 10 years now).
>
> What I still don't understand is some remaining details about this
> specific conversion for array pointers, even after C23 changes.
>
> Previously I wrote:
>
> "[...] now const-qualification applies not only to the elements, but
> also to the entire array type as well. [...] It now falls under the
> "usual" const-correctness rules. In C23 arrays are no longer special
> in such contexts"
>
> But on the second thought, this is oversimplifying things. What about
> remaining rules of type compatibility wrt const-qualification of array
> elements?
I think I see where you're going here. Let's see if we can clear
up the seeming contradictions. Forgive me if I meander a bit.
> Again, when we do something like this:
>
> typedef int A[10];
> A a;
> const A *pa = &a;
>
> this is equivalent, speaking informally, to
>
> int a[10];
> const int (const *pa)[10] = &a;
>
> i.e. as C23 states, the const-qualification is applied to both the
> array itself and to its elements. (Yes, I know that the `pa`
> declaration is formally invalid. This version is intended as a
> sketch.)
I'd like to rewrite these two lines, using a slightly different
syntax to help the subsequent explanation:
int [10] a;
int const [10] const *pa = &a;
In this syntax declarations are read right-to-left, with each
'const' applying to what is to its immediate left.
> So, the `const` that applies to the array itself does indeed fall
> under the "usual const-correctness rules" - we are just adding `const`
> in a pointer conversion. Nothing to see here.
>
> But what about the `const` on the array elements? It is still there
> even in C23. Good old C type compatibility rules state that for two
> arrays types to be compatible their element types have to be
> compatible. And the latter requires identical qualification.
To address this question let's change the scenario slightly. First
I want to be able to write a 'struct' type without the keyword, and
also with the rule that keyword-less structs are the same if their
members are the same. Thus, the two declarations
{ int x; } foo = {1};
{ int x; } *pfoo = &foo;
are allowed, because the two keyword-less struct types are in
essence the same type.
Now some observations about the type of foo. If somewhere else
there were a separate declaration for foo (perhaps in a header
file), it could not be written as either
extern { int const x; } foo;
or as
extern { int x; } const foo;
because of type compatibility rules. Of course the point of
considering these alternatives is to reason analogously to array
types, but with the freedom to have the const-ness of the "element"
type be independent of the aggregate type.
Given the previous declaration/definition for foo, let's say at file
scope, we could declare a second variable cfoo -- this time as being
local to a function, and also const-qualified -- like so
{ int x; } const cfoo = foo;
because the "element" type of cfoo matches the element type of foo,
even though the aggregate types are different.
Now we want to ask about the type of cfoo.x. Obviously that type
must be int. But is it? It's kind of yes and no. If we take the
address of cfoo.x, it looks like its type cannot be int, because
this attempt to use it
int *pcfoo_s_x = &cfoo.x; // doesn't work
fails, for the obvious reason that we don't want to be able to
modify a const object by changing the "element" cfoo.x by using the
pointer pcfoo_s_x. So, sort of like arrays, the const-ness of the
outer keyword-less struct "falls through", in a sense, to the type
of the member x.
Let's enlarge the focus a bit. Surely we expect to be able to write
this declaration
{ int x; } const *p_unassignable_foo = &foo;
following the usual rules of address conversion (a pointer of type
X* can be converted to a pointer of type const X*). But wait! We
already agreed that a second declaration of foo with
extern { int x; } const foo;
isn't allowed, because of type incompatibility. So why is it that the
address of foo can be converted to a pointer to an _incompatible_ type
in the assignement to p_unassignable_foo? Of course the simple answer
is that the language allows it. The more satisfying answer is that
the language allows the conversion because it is safe, even though the
pointed-to types are not compatible. The const-ness of the "element"
x is not relevant to the question -- it's safe to assign a X* to a
const X*, and thus it's allowed, with the caveat that to make it work
we have to insist that an assignment like
p_unassignable_foo->x = 17;
be disallowed.
I expect you can run this explanation backwards to the array case,
and see why a pointer to an array can be converted to a pointer to a
C23-const array makes sense, even though there is a level of type
incompatibility involved in the two types involved. The conversion
is safe, and that's why it's allowed; the const-ness of the element
type is just a detail to be considered in deciding how to make the
conversion not violate what we expect for const-qualified types.
> In the above case, since in C23 `const` continues to fall-through to
> array elements, const-qualification of the element type does not
> match: one array type has `int` elements, another - `const int`
> elements. So, why is
>
> const A *pa = &a;
>
> valid in C23? Am I missing another little change somewhere in C23?
The answer is the compatibility of the pointed to types doesn't
matter. The conversion of the pointer type is allowed because it
preserves our expectation for how const-qualified types behave, and
the compability of the pointed-to types was just a red herring.
I'm sorry to take so long to get to the point. My explanation
reflects the thought process that I went through to understand
and then answer your question. I hope it has cleared up how to
understand the new rules for array const-ness.
Back to comp.lang.c | Previous | Next — Previous in thread | Find similar
pedantic gcc and const 2D arrays Michael S <already5chosen@yahoo.com> - 2026-04-09 01:21 +0300
Re: pedantic gcc and const 2D arrays Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-04-08 15:57 -0700
Re: pedantic gcc and const 2D arrays Michael S <already5chosen@yahoo.com> - 2026-04-09 03:09 +0300
Re: pedantic gcc and const 2D arrays 🇵🇱Jacek Marcin Jaworski🇵🇱 <jmj@energokod.gda.pl> - 2026-04-09 02:33 +0200
Re: pedantic gcc and const 2D arrays Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-04-08 21:42 -0700
Re: pedantic gcc and const 2D arrays Andrey Tarasevich <noone@noone.net> - 2026-04-08 20:34 -0700
Re: pedantic gcc and const 2D arrays Michael S <already5chosen@yahoo.com> - 2026-04-09 11:09 +0300
Re: pedantic gcc and const 2D arrays "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-04-09 02:38 -0700
Re: pedantic gcc and const 2D arrays Michael S <already5chosen@yahoo.com> - 2026-04-09 14:06 +0300
Re: pedantic gcc and const 2D arrays "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-04-09 13:09 -0700
Re: pedantic gcc and const 2D arrays Andrey Tarasevich <noone@noone.net> - 2026-04-12 11:30 -0700
Re: pedantic gcc and const 2D arrays Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-04-13 05:40 -0700
Re: pedantic gcc and const 2D arrays Andrey Tarasevich <noone@noone.net> - 2026-04-26 13:45 -0700
Re: pedantic gcc and const 2D arrays Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-04-27 07:27 -0700
csiph-web