Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #390095 > unrolled thread

Struct Error

Started bybart <bc@freeuk.com>
First post2025-01-22 16:14 +0000
Last post2025-02-02 20:35 -0800
Articles 18 on this page of 38 — 14 participants

Back to article view | Back to comp.lang.c


Contents

  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]


#390112

FromLawrence D'Oliveiro <ldo@nz.invalid>
Date2025-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]


#390114

Frombart <bc@freeuk.com>
Date2025-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]


#390116

FromLawrence D'Oliveiro <ldo@nz.invalid>
Date2025-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]


#390118

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2025-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]


#390119

Frombart <bc@freeuk.com>
Date2025-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]


#390129

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2025-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]


#390135

FromMichael S <already5chosen@yahoo.com>
Date2025-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]


#390175

Frombart <bc@freeuk.com>
Date2025-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]


#390176

FromMichael S <already5chosen@yahoo.com>
Date2025-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]


#390177

FromKaz Kylheku <643-408-1753@kylheku.com>
Date2025-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]


#390179

Frombart <bc@freeuk.com>
Date2025-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]


#390185

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2025-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]


#390186

Frombart <bc@freeuk.com>
Date2025-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]


#390199

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2025-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]


#390190

FromRichard Damon <richard@damon-family.org>
Date2025-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]


#390191

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2025-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]


#390104

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2025-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]


#390205

FromAndrey Tarasevich <noone@noone.net>
Date2025-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