Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #390095 > unrolled thread
| Started by | bart <bc@freeuk.com> |
|---|---|
| First post | 2025-01-22 16:14 +0000 |
| Last post | 2025-02-02 20:35 -0800 |
| Articles | 18 on this page of 38 — 14 participants |
Back to article view | Back to comp.lang.c
Struct Error bart <bc@freeuk.com> - 2025-01-22 16:14 +0000
Re: Struct Error Kaz Kylheku <643-408-1753@kylheku.com> - 2025-01-22 20:05 +0000
Re: Struct Error Ben Bacarisse <ben@bsb.me.uk> - 2025-01-22 21:00 +0000
Re: Struct Error Richard Harnden <richard.nospam@gmail.invalid> - 2025-01-22 20:08 +0000
Re: Struct Error Lawrence D'Oliveiro <ldo@nz.invalid> - 2025-01-22 22:27 +0000
Re: Struct Error James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-01-22 20:05 -0500
Re: Struct Error learningcpp1@gmail.com (m137) - 2025-01-23 03:49 +0000
Re: Struct Error Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-01-22 23:15 -0800
Re: Struct Error James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-01-23 03:37 -0500
Re: Struct Error Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-01-22 23:31 -0800
Re: Struct Error bart <bc@freeuk.com> - 2025-01-23 10:54 +0000
Re: Struct Error BGB <cr88192@gmail.com> - 2025-01-23 14:58 -0600
Re: Struct Error bart <bc@freeuk.com> - 2025-01-24 00:51 +0000
Re: Struct Error BGB <cr88192@gmail.com> - 2025-01-24 00:27 -0600
Re: Struct Error David Brown <david.brown@hesbynett.no> - 2025-01-24 09:45 +0100
Re: Struct Error Kaz Kylheku <643-408-1753@kylheku.com> - 2025-01-24 20:31 +0000
Re: Struct Error bart <bc@freeuk.com> - 2025-01-24 22:53 +0000
Re: Struct Error James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-01-24 20:53 -0500
Re: Struct Error James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-01-24 08:43 -0500
Re: Struct Error bart <bc@freeuk.com> - 2025-01-24 23:32 +0000
Re: Struct Error Lawrence D'Oliveiro <ldo@nz.invalid> - 2025-01-23 23:50 +0000
Re: Struct Error bart <bc@freeuk.com> - 2025-01-24 00:37 +0000
Re: Struct Error Lawrence D'Oliveiro <ldo@nz.invalid> - 2025-01-24 00:57 +0000
Re: Struct Error Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-01-23 17:23 -0800
Re: Struct Error bart <bc@freeuk.com> - 2025-01-24 01:27 +0000
Re: Struct Error James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-01-24 08:24 -0500
Re: Struct Error Michael S <already5chosen@yahoo.com> - 2025-01-24 16:37 +0200
Re: Struct Error bart <bc@freeuk.com> - 2025-01-26 19:14 +0000
Re: Struct Error Michael S <already5chosen@yahoo.com> - 2025-01-26 23:14 +0200
Re: Struct Error Kaz Kylheku <643-408-1753@kylheku.com> - 2025-01-27 04:05 +0000
Re: Struct Error bart <bc@freeuk.com> - 2025-01-27 20:19 +0000
Re: Struct Error Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-01-29 02:59 -0800
Re: Struct Error bart <bc@freeuk.com> - 2025-01-29 11:36 +0000
Re: Struct Error Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-01-30 11:51 -0800
Re: Struct Error Richard Damon <richard@damon-family.org> - 2025-01-29 07:32 -0500
Re: Struct Error Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-01-29 07:52 -0800
Re: Struct Error Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-01-22 23:11 -0800
Re: Struct Error Andrey Tarasevich <noone@noone.net> - 2025-02-02 20:35 -0800
Page 2 of 2 — ← Prev page 1 [2]
| From | Lawrence D'Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2025-01-23 23:50 +0000 |
| Message-ID | <vmukk4$1s5se$3@dont-email.me> |
| In reply to | #390109 |
On Thu, 23 Jan 2025 10:54:10 +0000, bart wrote: > Wouldn't this also be the case here: > > struct scenet *child; > }; > > The struct is incomplete, but it still knows how to do pointer > arithmetic with that member. No, because there is no pointer arithmetic involved in processing that declaration. Of course you will get a suitable error in a subsequent expression that does involve such pointer arithmetic, if the struct has not been fully defined by that point.
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-01-24 00:37 +0000 |
| Message-ID | <vmunc7$1snhv$1@dont-email.me> |
| In reply to | #390112 |
On 23/01/2025 23:50, Lawrence D'Oliveiro wrote:
> On Thu, 23 Jan 2025 10:54:10 +0000, bart wrote:
>
>> Wouldn't this also be the case here:
>>
>> struct scenet *child;
>> };
>>
>> The struct is incomplete, but it still knows how to do pointer
>> arithmetic with that member.
>
> No, because there is no pointer arithmetic involved in processing that
> declaration.
Neither of these member declarations involve any expression:
....
struct scenet *childp;
struct scenet (*childa)[];
};
Yet childp is fine, but childa is a gcc compiler error. Why is that?
When expressions are used later on, both need to know the size of
struct, which has been determined by then.
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D'Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2025-01-24 00:57 +0000 |
| Message-ID | <vmuoh2$1sjgj$5@dont-email.me> |
| In reply to | #390114 |
On Fri, 24 Jan 2025 00:37:27 +0000, bart wrote: > Yet childp is fine, but childa is a gcc compiler error. Why is that? Because it needs to know the size of the type to work out the function type’s calling convention.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2025-01-23 17:23 -0800 |
| Message-ID | <87tt9p57j1.fsf@nosuchdomain.example.com> |
| In reply to | #390116 |
Lawrence D'Oliveiro <ldo@nz.invalid> writes:
> On Fri, 24 Jan 2025 00:37:27 +0000, bart wrote:
[snipped context restored]
>> struct scenet *childp;
>> struct scenet (*childa)[];
>> };
>> Yet childp is fine, but childa is a gcc compiler error. Why is that?
>
> Because it needs to know the size of the type to work out the function
> type’s calling convention.
I restored the context you snipped. There is no function type in the
code Bart was asking about. childa is defined as a pointer to an
(incomplete) array of struct scenet.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-01-24 01:27 +0000 |
| Message-ID | <vmuq9b$1t76o$1@dont-email.me> |
| In reply to | #390116 |
On 24/01/2025 00:57, Lawrence D'Oliveiro wrote: > On Fri, 24 Jan 2025 00:37:27 +0000, bart wrote: > >> Yet childp is fine, but childa is a gcc compiler error. Why is that? > > Because it needs to know the size of the type to work out the function > type’s calling convention. OK. So you've no idea what you're talking about. That's fine.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2025-01-24 08:24 -0500 |
| Message-ID | <vn04a6$28aoo$1@dont-email.me> |
| In reply to | #390109 |
On 1/23/2025 4:54 AM, bart wrote:
> On 23/01/2025 01:05, James Kuyper wrote:
>> On 2025-01-22, bart <bc@freeuk.com> wrote:
>>> Gcc 14.1 gives me an error compiling this code:
>>>
>>> struct vector;
>>> struct scenet;
>>>
>>> struct vector {
>>> double x;
>>> double y;
>>> double z;
>>> };
>>>
>>> struct scenet {
>>> struct vector center;
>>> double radius;
>>> struct scenet (*child)[];
>>> };
>>
>> 6.7.6.2p2: "The element type shall not be an incomplete or function
>> type."
>>
>> I have many draft versions of the C standard. n2912.pdf, dated
>> 2022-06-08, says in 6.7.2.1.p3 about struct types that "... the type is
>> incomplete144) until immediately after the closing brace of the list
>> defining the content, and complete thereafter."
>>
>> Therefore, struct scenet is not a complete type until the closing brace
>> of it's declaration.
>
> Wouldn't this also be the case here:
>
> struct scenet *child;
> };
>
> The struct is incomplete, but it still knows how to do pointer
> arithmetic with that member. The calculation is not that different from
> the array version (actually, the code from my compiler is identical).
The difference is that there's an explicit requirement that the element
type of an array type be complete. As far as I know, there's no such
requirement that applies when you have a pointer to incomplete type,
rather than an array of an incomplete type. If you think otherwise,
please identify the requirement. I started reviewing all the places
where the standard says something about complete and incomplete types,
but there's way too many of them.
The reason, I think, is the following:
"A pointer to void shall have the same representation and alignment
requirements as a pointer to a character type.53) Similarly, pointers to
qualified or unqualified versions of compatible types shall have the
same representation and alignment requirements. All pointers to
structure types shall have the same representation and alignment
requirements as each other. All pointers to union types shall have the
same representation and alignment requirements as each other. Pointers
to other types need not have the same representation or alignment
requirements." (6.2.5p33)
This means that, in principle, the representation and alignment of a
pointer to an array of an incomplete struct type might depend upon the
unknown content of that struct type, if only through the size of the
type. So a pointer to an array of an incomplete type presents a possible
challenge that isn't a problem for a pointer to an object of that
incomplete type.
I'm sure that you're used to platforms where all pointers to object
types have the same representation and alignment requirements - most
developers are. However, there are very real platforms where that isn't
the case, and the C standard goes out of its way to permit conforming
implementations of C on such platforms.
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-01-24 16:37 +0200 |
| Message-ID | <20250124163740.00006281@yahoo.com> |
| In reply to | #390109 |
On Thu, 23 Jan 2025 10:54:10 +0000
bart <bc@freeuk.com> wrote:
> On 23/01/2025 01:05, James Kuyper wrote:
> > On 2025-01-22, bart <bc@freeuk.com> wrote:
> >> Gcc 14.1 gives me an error compiling this code:
> >>
> >> struct vector;
> >> struct scenet;
> >>
> >> struct vector {
> >> double x;
> >> double y;
> >> double z;
> >> };
> >>
> >> struct scenet {
> >> struct vector center;
> >> double radius;
> >> struct scenet (*child)[];
> >> };
> >
> > 6.7.6.2p2: "The element type shall not be an incomplete or function
> > type."
> >
> > I have many draft versions of the C standard. n2912.pdf, dated
> > 2022-06-08, says in 6.7.2.1.p3 about struct types that "... the
> > type is incomplete144) until immediately after the closing brace of
> > the list defining the content, and complete thereafter."
> >
> > Therefore, struct scenet is not a complete type until the closing
> > brace of it's declaration.
>
> Wouldn't this also be the case here:
>
> struct scenet *child;
> };
>
Just to point out if it was not said already: the problem is not related
specifically to recursive structures. It applies to arrays of
incomplete types in all circumstances.
struct bar;
struct bar (*bag)[]; // error
typedef struct bar (*bat)[]; // error
The case of the recursive structure is special only in a sense that it's
o.k. in C++, because [unlike C] in C++ struct considered complete within
its own body.
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-01-26 19:14 +0000 |
| Message-ID | <vn61ho$1pf2$1@dont-email.me> |
| In reply to | #390135 |
On 24/01/2025 14:37, Michael S wrote:
> On Thu, 23 Jan 2025 10:54:10 +0000
> bart <bc@freeuk.com> wrote:
>
>> On 23/01/2025 01:05, James Kuyper wrote:
>>> On 2025-01-22, bart <bc@freeuk.com> wrote:
>>>> Gcc 14.1 gives me an error compiling this code:
>>>>
>>>> struct vector;
>>>> struct scenet;
>>>>
>>>> struct vector {
>>>> double x;
>>>> double y;
>>>> double z;
>>>> };
>>>>
>>>> struct scenet {
>>>> struct vector center;
>>>> double radius;
>>>> struct scenet (*child)[];
>>>> };
>>>
>>> 6.7.6.2p2: "The element type shall not be an incomplete or function
>>> type."
>>>
>>> I have many draft versions of the C standard. n2912.pdf, dated
>>> 2022-06-08, says in 6.7.2.1.p3 about struct types that "... the
>>> type is incomplete144) until immediately after the closing brace of
>>> the list defining the content, and complete thereafter."
>>>
>>> Therefore, struct scenet is not a complete type until the closing
>>> brace of it's declaration.
>>
>> Wouldn't this also be the case here:
>>
>> struct scenet *child;
>> };
>>
>
> Just to point out if it was not said already: the problem is not related
> specifically to recursive structures. It applies to arrays of
> incomplete types in all circumstances.
>
> struct bar;
> struct bar (*bag)[]; // error
> typedef struct bar (*bat)[]; // error
I don't think anyone has yet explained why that is an error (other than
C says it is), but not this:
struct bar *ptr;
This is a pointer to an incomplete type. Attempts to do ++ptr for
example will fail later on if that struct has not yet been defined.
So why not the same for the pointer-to-array versions?
It just doesn't make sense.
Is it just because such pointers HAVE to work, otherwise
self-referential structs become impossible? That would make it a hack,
in which case why not apply it to arrays too?
> The case of the recursive structure is special only in a sense that it's
> o.k. in C++, because [unlike C] in C++ struct considered complete within
> its own body.
For non-recursive, you can choose to declare the pointer-to-array after
the struct has been fully defined.
[toc] | [prev] | [next] | [standalone]
| From | Michael S <already5chosen@yahoo.com> |
|---|---|
| Date | 2025-01-26 23:14 +0200 |
| Message-ID | <20250126231435.00005c02@yahoo.com> |
| In reply to | #390175 |
On Sun, 26 Jan 2025 19:14:00 +0000 bart <bc@freeuk.com> wrote: > > Is it just because such pointers HAVE to work, otherwise > self-referential structs become impossible? More important use case of poiner to incomplete struct is for abstract types with implementation completely hidden from the user.
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <643-408-1753@kylheku.com> |
|---|---|
| Date | 2025-01-27 04:05 +0000 |
| Message-ID | <20250126193003.409@kylheku.com> |
| In reply to | #390175 |
On 2025-01-26, bart <bc@freeuk.com> wrote:
> On 24/01/2025 14:37, Michael S wrote:
> This is a pointer to an incomplete type. Attempts to do ++ptr for
> example will fail later on if that struct has not yet been defined.
>
> So why not the same for the pointer-to-array versions?
>
> It just doesn't make sense.
You already know that GNU C++ silently accepts it, so this is
beating a dead horse.
Sure, something in a type not being specified is not a problem until the
information is actually needed for something. We can think about
a lazy type evaluation system. Functional programming languages
tend to have them.
But note that the rule /is/ actually consistent among aggregates.
Both an array and struct are aggregates. The elements are to
an array roughly the same thing that members are to a struct.
A struct may not have members of incomplete type,
An array may not have elements of incomplete type.
Your situation is this:
struct incomplete {
struct incomplete (*parray)[];
};
If we make a pointer to a struct rather than array,
it's the same kind of problem:
struct incomplete {
struct nested_incomplete {
struct incomplete memb;
} *pstruct;
};
In both cases, we have a pointer to something which
has an element, or member, of the incomplete type of
the outer struct which is to contain the pointer.
If the array version should work, so should the
struct version.
>> The case of the recursive structure is special only in a sense that it's
>> o.k. in C++, because [unlike C] in C++ struct considered complete within
>> its own body.
>
> For non-recursive, you can choose to declare the pointer-to-array after
> the struct has been fully defined.
If a C++ struct is complete within its own body, that means this should
be possible:
struct foo {
struct foo x;
int y;
};
That cannot be the reason why the pointer to array works in GNU C++.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-01-27 20:19 +0000 |
| Message-ID | <vn8po2$172j1$1@dont-email.me> |
| In reply to | #390177 |
On 27/01/2025 04:05, Kaz Kylheku wrote:
> On 2025-01-26, bart <bc@freeuk.com> wrote:
>> On 24/01/2025 14:37, Michael S wrote:
>> This is a pointer to an incomplete type. Attempts to do ++ptr for
>> example will fail later on if that struct has not yet been defined.
>>
>> So why not the same for the pointer-to-array versions?
>>
>> It just doesn't make sense.
>
> You already know that GNU C++ silently accepts it, so this is
> beating a dead horse.
C++ is no good to me. My old transpiler (now a deprecated product
anyway) generated C. Fixing it either means updating the transpiler (and
finding some hacky workaround like using casts everywhere) or doing that
manually to the generated C. Neither appeal.
> Your situation is this:
>
> struct incomplete {
> struct incomplete (*parray)[];
> };
>
> If we make a pointer to a struct rather than array,
> it's the same kind of problem:
>
> struct incomplete {
> struct nested_incomplete {
> struct incomplete memb;
> } *pstruct;
> };
>
> In both cases, we have a pointer to something which
> has an element, or member, of the incomplete type of
> the outer struct which is to contain the pointer.
It's trickier problem: I'm not sure myself what the size should be,
whereas that was easy to see with my array example. Here even TCC
reports it as incomplete. How my C compiler tells me the size is 8
bytes, which sounds reasonable given that the only concrete member in
there is one 64-bit pointer.
> If the array version should work, so should the
> struct version.
>
>>> The case of the recursive structure is special only in a sense that it's
>>> o.k. in C++, because [unlike C] in C++ struct considered complete within
>>> its own body.
>>
>> For non-recursive, you can choose to declare the pointer-to-array after
>> the struct has been fully defined.
>
> If a C++ struct is complete within its own body, that means this should
> be possible:
>
> struct foo {
> struct foo x;
> int y;
> };
This one seems impossible, and even C++ fails it. Because you're
directly including an actual struct within itself.
Still, my compiler is not bothered by it! It gives an overall size of 16
bytes and an offset for both x and y of 0. That embedded (incomplete)
version of struct foo uses the wrong size.
A similar example in my language gives a recursion failure.
However, examples like the ones in OP are well-defined: the member
involved is a single pointer of a fixed size.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2025-01-29 02:59 -0800 |
| Message-ID | <86jzad28d5.fsf@linuxsc.com> |
| In reply to | #390175 |
bart <bc@freeuk.com> writes:
> On 24/01/2025 14:37, Michael S wrote:
>
>> On Thu, 23 Jan 2025 10:54:10 +0000
>> bart <bc@freeuk.com> wrote:
>>
>>> On 23/01/2025 01:05, James Kuyper wrote:
>>>
>>>> On 2025-01-22, bart <bc@freeuk.com> wrote:
>>>>
>>>>> Gcc 14.1 gives me an error compiling this code:
>>>>>
>>>>> struct vector;
>>>>> struct scenet;
>>>>>
>>>>> struct vector {
>>>>> double x;
>>>>> double y;
>>>>> double z;
>>>>> };
>>>>>
>>>>> struct scenet {
>>>>> struct vector center;
>>>>> double radius;
>>>>> struct scenet (*child)[];
>>>>> };
>>>>
>>>> 6.7.6.2p2: "The element type shall not be an incomplete or
>>>> function type."
>>>>
>>>> I have many draft versions of the C standard. n2912.pdf, dated
>>>> 2022-06-08, says in 6.7.2.1.p3 about struct types that "... the
>>>> type is incomplete144) until immediately after the closing brace
>>>> of the list defining the content, and complete thereafter."
>>>>
>>>> Therefore, struct scenet is not a complete type until the closing
>>>> brace of it's declaration.
>>>
>>> Wouldn't this also be the case here:
>>>
>>> struct scenet *child;
>>> };
>>
>> Just to point out if it was not said already: the problem is not
>> related specifically to recursive structures. It applies to arrays
>> of incomplete types in all circumstances.
>>
>> struct bar;
>> struct bar (*bag)[]; // error
>> typedef struct bar (*bat)[]; // error
>
> I don't think anyone has yet explained why that is an error (other
> than C says it is), but not this:
>
> struct bar *ptr;
>
> This is a pointer to an incomplete type. Attempts to do ++ptr
> for example will fail later on if that struct has not yet been
> defined.
>
> So why not the same for the pointer-to-array versions?
The question you should be asking is why did the original C
standards body make the rule they did?
The answer might be because this exception to a simple and
general rule is almost never useful, and never necessary.
Considering that it has been 35 years since that original rule
was made, and 2025 is the first time the question has come up,
the indications are that the original decision was a good one.
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-01-29 11:36 +0000 |
| Message-ID | <vnd3rl$2bqlb$1@dont-email.me> |
| In reply to | #390185 |
On 29/01/2025 10:59, Tim Rentsch wrote:
> bart <bc@freeuk.com> writes:
>
>> On 24/01/2025 14:37, Michael S wrote:
>>
>>> On Thu, 23 Jan 2025 10:54:10 +0000
>>> bart <bc@freeuk.com> wrote:
>>>
>>>> On 23/01/2025 01:05, James Kuyper wrote:
>>>>
>>>>> On 2025-01-22, bart <bc@freeuk.com> wrote:
>>>>>
>>>>>> Gcc 14.1 gives me an error compiling this code:
>>>>>>
>>>>>> struct vector;
>>>>>> struct scenet;
>>>>>>
>>>>>> struct vector {
>>>>>> double x;
>>>>>> double y;
>>>>>> double z;
>>>>>> };
>>>>>>
>>>>>> struct scenet {
>>>>>> struct vector center;
>>>>>> double radius;
>>>>>> struct scenet (*child)[];
>>>>>> };
>>>>>
>>>>> 6.7.6.2p2: "The element type shall not be an incomplete or
>>>>> function type."
>>>>>
>>>>> I have many draft versions of the C standard. n2912.pdf, dated
>>>>> 2022-06-08, says in 6.7.2.1.p3 about struct types that "... the
>>>>> type is incomplete144) until immediately after the closing brace
>>>>> of the list defining the content, and complete thereafter."
>>>>>
>>>>> Therefore, struct scenet is not a complete type until the closing
>>>>> brace of it's declaration.
>>>>
>>>> Wouldn't this also be the case here:
>>>>
>>>> struct scenet *child;
>>>> };
>>>
>>> Just to point out if it was not said already: the problem is not
>>> related specifically to recursive structures. It applies to arrays
>>> of incomplete types in all circumstances.
>>>
>>> struct bar;
>>> struct bar (*bag)[]; // error
>>> typedef struct bar (*bat)[]; // error
>>
>> I don't think anyone has yet explained why that is an error (other
>> than C says it is), but not this:
>>
>> struct bar *ptr;
>>
>> This is a pointer to an incomplete type. Attempts to do ++ptr
>> for example will fail later on if that struct has not yet been
>> defined.
>>
>> So why not the same for the pointer-to-array versions?
>
> The question you should be asking is why did the original C
> standards body make the rule they did?
>
> The answer might be because this exception to a simple and
> general rule is almost never useful, and never necessary.
Well, you never see such a thing in use, certainly. I wonder why that is!
When a language outlaws some particular construction, forcing people to
stick to a particular idiom (the common use of a T* type to work with
pointers and arrays instead of the more sensible and safer T(*)[]), then
clearly you're not going to see such uses in the field.
Although there are really two parts to it: use of T(*)[] generally
(outside of self-referential structs) is allowed, but that is still
rare, presumably because the syntax is too unwieldy. Or people simply
don't know about it, since everyone uses T*.
My use-case was within generated code, so that aspect was not relevant.
> Considering that it has been 35 years since that original rule
> was made, and 2025 is the first time the question has come up,
> the indications are that the original decision was a good one.
We don't know that. Perhaps it comes up all the time, people realise
they can't use such a construct, and use a different approach.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2025-01-30 11:51 -0800 |
| Message-ID | <86zfj8yt9f.fsf@linuxsc.com> |
| In reply to | #390186 |
bart <bc@freeuk.com> writes:
> On 29/01/2025 10:59, Tim Rentsch wrote:
>
>> bart <bc@freeuk.com> writes:
>>
>>> On 24/01/2025 14:37, Michael S wrote:
>>>
>>>> On Thu, 23 Jan 2025 10:54:10 +0000
>>>> bart <bc@freeuk.com> wrote:
>>>>
>>>>> On 23/01/2025 01:05, James Kuyper wrote:
>>>>>
>>>>>> On 2025-01-22, bart <bc@freeuk.com> wrote:
>>>>>>
>>>>>>> Gcc 14.1 gives me an error compiling this code:
>>>>>>>
>>>>>>> struct vector;
>>>>>>> struct scenet;
>>>>>>>
>>>>>>> struct vector {
>>>>>>> double x;
>>>>>>> double y;
>>>>>>> double z;
>>>>>>> };
>>>>>>>
>>>>>>> struct scenet {
>>>>>>> struct vector center;
>>>>>>> double radius;
>>>>>>> struct scenet (*child)[];
>>>>>>> };
>>>>>>
>>>>>> 6.7.6.2p2: "The element type shall not be an incomplete or
>>>>>> function type."
>>>>>>
>>>>>> I have many draft versions of the C standard. n2912.pdf, dated
>>>>>> 2022-06-08, says in 6.7.2.1.p3 about struct types that "... the
>>>>>> type is incomplete144) until immediately after the closing brace
>>>>>> of the list defining the content, and complete thereafter."
>>>>>>
>>>>>> Therefore, struct scenet is not a complete type until the closing
>>>>>> brace of it's declaration.
>>>>>
>>>>> Wouldn't this also be the case here:
>>>>>
>>>>> struct scenet *child;
>>>>> };
>>>>
>>>> Just to point out if it was not said already: the problem is not
>>>> related specifically to recursive structures. It applies to arrays
>>>> of incomplete types in all circumstances.
>>>>
>>>> struct bar;
>>>> struct bar (*bag)[]; // error
>>>> typedef struct bar (*bat)[]; // error
>>>
>>> I don't think anyone has yet explained why that is an error (other
>>> than C says it is), but not this:
>>>
>>> struct bar *ptr;
>>>
>>> This is a pointer to an incomplete type. Attempts to do ++ptr
>>> for example will fail later on if that struct has not yet been
>>> defined.
>>>
>>> So why not the same for the pointer-to-array versions?
>>
>> The question you should be asking is why did the original C
>> standards body make the rule they did?
>>
>> The answer might be because this exception to a simple and
>> general rule is almost never useful, and never necessary.
>
> Well, you never see such a thing in use, certainly. I wonder why
> that is!
>
> When a language outlaws some particular construction, forcing
> people to stick to a particular idiom (the common use of a T* type
> to work with pointers and arrays instead of the more sensible and
> safer T(*)[]), then clearly you're not going to see such uses in
> the field.
>
> Although there are really two parts to it: use of T(*)[]
> generally (outside of self-referential structs) is allowed, but
> that is still rare, presumably because the syntax is too unwieldy.
> Or people simply don't know about it, since everyone uses T*.
I didn't say this use case isn't used. I said this use case is
almost never useful.
>> Considering that it has been 35 years since that original rule
>> was made, and 2025 is the first time the question has come up,
>> the indications are that the original decision was a good one.
>
> We don't know that. Perhaps it comes up all the time, people
> realise they can't use such a construct, and use a different
> approach.
We don't know that there has never been a person 50 feet tall
either, but that doesn't mean there has been one.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <richard@damon-family.org> |
|---|---|
| Date | 2025-01-29 07:32 -0500 |
| Message-ID | <3cd9101a43de105e6aaa74614d05fcba5b8c093c@i2pn2.org> |
| In reply to | #390185 |
On 1/29/25 5:59 AM, Tim Rentsch wrote:
> bart <bc@freeuk.com> writes:
>
>> On 24/01/2025 14:37, Michael S wrote:
>>
>>> On Thu, 23 Jan 2025 10:54:10 +0000
>>> bart <bc@freeuk.com> wrote:
>>>
>>>> On 23/01/2025 01:05, James Kuyper wrote:
>>>>
>>>>> On 2025-01-22, bart <bc@freeuk.com> wrote:
>>>>>
>>>>>> Gcc 14.1 gives me an error compiling this code:
>>>>>>
>>>>>> struct vector;
>>>>>> struct scenet;
>>>>>>
>>>>>> struct vector {
>>>>>> double x;
>>>>>> double y;
>>>>>> double z;
>>>>>> };
>>>>>>
>>>>>> struct scenet {
>>>>>> struct vector center;
>>>>>> double radius;
>>>>>> struct scenet (*child)[];
>>>>>> };
>>>>>
>>>>> 6.7.6.2p2: "The element type shall not be an incomplete or
>>>>> function type."
>>>>>
>>>>> I have many draft versions of the C standard. n2912.pdf, dated
>>>>> 2022-06-08, says in 6.7.2.1.p3 about struct types that "... the
>>>>> type is incomplete144) until immediately after the closing brace
>>>>> of the list defining the content, and complete thereafter."
>>>>>
>>>>> Therefore, struct scenet is not a complete type until the closing
>>>>> brace of it's declaration.
>>>>
>>>> Wouldn't this also be the case here:
>>>>
>>>> struct scenet *child;
>>>> };
>>>
>>> Just to point out if it was not said already: the problem is not
>>> related specifically to recursive structures. It applies to arrays
>>> of incomplete types in all circumstances.
>>>
>>> struct bar;
>>> struct bar (*bag)[]; // error
>>> typedef struct bar (*bat)[]; // error
>>
>> I don't think anyone has yet explained why that is an error (other
>> than C says it is), but not this:
>>
>> struct bar *ptr;
>>
>> This is a pointer to an incomplete type. Attempts to do ++ptr
>> for example will fail later on if that struct has not yet been
>> defined.
>>
>> So why not the same for the pointer-to-array versions?
>
> The question you should be asking is why did the original C
> standards body make the rule they did?
My guess is that it makes the simplest implementation of a C compiler
much more complicated. While I don't think it has been explicited
stated, one goal the original language, and apparently kept by the
Standards Comittee, has been to make the language fairly simple to
proceess to get working code. To optimize to make fast, might take more
work, but to make your first complier for a system should be straight
forward. I believe a C compiler can still be done with a single pass
through the source code, with limited look ahead, and only the final
"link" step needs to be able to handle large chunks of the program.
Allowing the pointer to array time to be based on an incomplete type
might make this goal harder.
>
> The answer might be because this exception to a simple and
> general rule is almost never useful, and never necessary.
>
> Considering that it has been 35 years since that original rule
> was made, and 2025 is the first time the question has come up,
> the indications are that the original decision was a good one.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2025-01-29 07:52 -0800 |
| Message-ID | <86cyg51uta.fsf@linuxsc.com> |
| In reply to | #390190 |
Richard Damon <richard@damon-family.org> writes:
> On 1/29/25 5:59 AM, Tim Rentsch wrote:
>
>> bart <bc@freeuk.com> writes:
>>
>>> On 24/01/2025 14:37, Michael S wrote:
>>>
>>>> On Thu, 23 Jan 2025 10:54:10 +0000
>>>> bart <bc@freeuk.com> wrote:
>>>>
>>>>> On 23/01/2025 01:05, James Kuyper wrote:
>>>>>
>>>>>> On 2025-01-22, bart <bc@freeuk.com> wrote:
>>>>>>
>>>>>>> Gcc 14.1 gives me an error compiling this code:
>>>>>>>
>>>>>>> struct vector;
>>>>>>> struct scenet;
>>>>>>>
>>>>>>> struct vector {
>>>>>>> double x;
>>>>>>> double y;
>>>>>>> double z;
>>>>>>> };
>>>>>>>
>>>>>>> struct scenet {
>>>>>>> struct vector center;
>>>>>>> double radius;
>>>>>>> struct scenet (*child)[];
>>>>>>> };
>>>>>>
>>>>>> 6.7.6.2p2: "The element type shall not be an incomplete or
>>>>>> function type."
>>>>>>
>>>>>> I have many draft versions of the C standard. n2912.pdf, dated
>>>>>> 2022-06-08, says in 6.7.2.1.p3 about struct types that "... the
>>>>>> type is incomplete144) until immediately after the closing brace
>>>>>> of the list defining the content, and complete thereafter."
>>>>>>
>>>>>> Therefore, struct scenet is not a complete type until the closing
>>>>>> brace of it's declaration.
>>>>>
>>>>> Wouldn't this also be the case here:
>>>>>
>>>>> struct scenet *child;
>>>>> };
>>>>
>>>> Just to point out if it was not said already: the problem is not
>>>> related specifically to recursive structures. It applies to arrays
>>>> of incomplete types in all circumstances.
>>>>
>>>> struct bar;
>>>> struct bar (*bag)[]; // error
>>>> typedef struct bar (*bat)[]; // error
>>>
>>> I don't think anyone has yet explained why that is an error (other
>>> than C says it is), but not this:
>>>
>>> struct bar *ptr;
>>>
>>> This is a pointer to an incomplete type. Attempts to do ++ptr
>>> for example will fail later on if that struct has not yet been
>>> defined.
>>>
>>> So why not the same for the pointer-to-array versions?
>>
>> The question you should be asking is why did the original C
>> standards body make the rule they did?
>
> My guess is that it makes the simplest implementation of a C compiler
> much more complicated. While I don't think it has been explicited
> stated, one goal the original language, and apparently kept by the
> Standards Comittee, has been to make the language fairly simple to
> proceess to get working code. To optimize to make fast, might take
> more work, but to make your first complier for a system should be
> straight forward. I believe a C compiler can still be done with a
> single pass through the source code, with limited look ahead, and only
> the final "link" step needs to be able to handle large chunks of the
> program.
>
> Allowing the pointer to array time to be based on an incomplete type
> might make this goal harder.
Possibly. I suspect the question was never considered, simply
because it never came up. It's unusual even to have a pointer to
an array with unknown extent, and an array with an incomplete
element type is an even weirder beast. It's easy to believe that
the peculiar circumstances of the situation being asked about
just never occurred to anyone. Given that, the simple rule in
the C standard has an obvious and natural appeal.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2025-01-22 23:11 -0800 |
| Message-ID | <867c6m3sxx.fsf@linuxsc.com> |
| In reply to | #390095 |
bart <bc@freeuk.com> writes:
> Gcc 14.1 gives me an error compiling this code:
>
> struct vector;
> struct scenet;
>
> struct vector {
> double x;
> double y;
> double z;
> };
>
> struct scenet {
> struct vector center;
> double radius;
> struct scenet (*child)[];
> };
>
> The error is:
>
> error: array type has incomplete element type 'struct scenet'
> struct scenet (*child)[];
> ^~~~~
>
> Is there any way to fix this, or is it not possible?
>
> (This comes from generated code. Idiomatic C would use a T* here
> rather than T(*)[], but that is not an option. Other compilers like
> tcc, DMC and mine have no problem with it.)
The code shown violates a constraint in the C standard, because
the element type of the array declarator is an incomplete type
at the point the 'child' member is declared, so a diagnostic
is required.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <noone@noone.net> |
|---|---|
| Date | 2025-02-02 20:35 -0800 |
| Message-ID | <vnph3i$13tcm$1@dont-email.me> |
| In reply to | #390095 |
On Wed 1/22/2025 8:14 AM, bart wrote:
> Gcc 14.1 gives me an error compiling this code:
>
> struct vector;
> struct scenet;
>
> struct vector {
> double x;
> double y;
> double z;
> };
>
> struct scenet {
> struct vector center;
> double radius;
> struct scenet (*child)[];
> };
>
> The error is:
>
> error: array type has incomplete element type 'struct scenet'
> struct scenet (*child)[];
> ^~~~~
>
> Is there any way to fix this, or is it not possible?
C has always been very strict about completeness of the element type in
array declarations. The element type has to be complete, period.
Another manifestation of the same issue is demonstrated by the following
example
struct S;
void foo(struct S a[]) {}
The function parameter declaration is invalid in C sue to incompleteness
of `struct S`. Even though the declaration will be implicitly adjusted
anyway to
void foo(struct S *a) {}
and this adjusted version is perfectly valid the in C (despite
incompleteness of `struct S`), the language still rejects the original
variant.
C++ is more lenient in such contexts.
--
Best regards,
Andrey
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web