Sujet : Re: Struct Error
De : bc (at) *nospam* freeuk.com (bart)
Groupes : comp.lang.cDate : 25. Jan 2025, 00:32:53
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vn17v4$2ej5b$2@dont-email.me>
References : 1 2 3 4 5 6
User-Agent : Mozilla Thunderbird
On 24/01/2025 13:43, James Kuyper wrote:
On 1/23/2025 6:51 PM, bart wrote:
On 23/01/2025 20:58, BGB wrote:
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).
>
>
Difference is, in this case, "sizeof(struct scenet)" is not relevant
to "sizeof(struct scenet *)".
>
>
No, both of these need to know the size of the struct when accessing the
i'th element:
>
....
struct scenet *childp;
struct scenet (*childa)[];
};
>
The only thing you can't do with x->childa is perform pointer arithmetic
on the whole pointer-to-array, since the array size is zero. But doing
(x->childa)[i] should be fine.
>
As is clear since other compilers (excluding those that lavishly copy
gcc's behaviour) have no problem with it.
The problem is not what you can do with the pointer, but the alignment
and representation of the pointer itself. Those are uniquely determined
for childp by the fact that it's a pointer to a struct type, regardless
of the content of that type (6.2.5p33). The alignment and representation
of childa, on the other hand, could depend upon the content of struct
scenet (in particular, the size of that struct type). It needs to know
those requirements, in order to complete the definition of struct
scenet. That's not an insoluble problem: just choose an alignment and
representation for childa that allows a pointer to the entire struct to
have that same alignment and representation - but the standard chose not
to mandate that it be solved.
If you've never tried to create a compiler for a platform where it makes
sense to have pointers to object types with different alignment and
representations, depending upon the type that they point at, you
probably have no idea what would be involved in solving that problem (I
certainly don't).
Since the vast majority of machines have no such problems, why should this affect the users of those machines?
It seems perfectly reasonable to me to have a pointer to an unbounded array (it's little different to void*), and to be able to use such a pointer within a struct.
C already allows self-referential structs, so that shouldn't be a problem either. The calculation required for indexing such an array depends on the size of the struct, and this will be known by that point.
The context here is that of a language where that feature is well-defined, using C as an intermediate represention, and compiling for a machine where the required pointers are all well-defined (every pointer for code or data) is a 64-bit value.
So gcc's behaviour here is not helpful and not useful; what problem is it trying to avoid that would cause chaos on my x64 platform?
The alighnment of the struct should also not affect the code generated for the array access, and itself should not be affected by that choice of type.