bart <
bc@freeuk.com> writes:
On 10/04/2025 17:51, Kaz Kylheku wrote:
On 2025-04-10, bart <bc@freeuk.com> wrote:
>
Do you agree with that? Or is there something more to making two types
be incompatible?
Tim: two fingerprints from the left hand index finger are from
different
humans if they are different.
You: do you agree with this, or is there more that can make
two humans different?
Struct compatibility is determined by tag and content.
>
This is more nuanced. There is two structs being the same type or not,
which a compiler can determine if they are in the same translation
unit; no need to analyse tags or anything to figure that out, it's
either the exact same type or not.
>
And there is two structs in two translation units which have separate
definitions, which the compiler cannot compare, and which have to be
compatible for the program to be valid. But the compiler cannot check
that.
>
The example was like this:
>
module A: typedef struct point {float a; float b;} Point;
>
module B: typedef float length;
typedef struct _tag {length x, y;} vector;
I know I said I didn't care about the specific types, but now that I've
seen a concise example (via a followup someone else posted), I've
decided to take a look. I'm allowed to change my mind.
I'll assume that "module A" and "module B" mean that the two
declarations are in different translation units. I'll assume that
the declarations are *exactly* like the above. I won't assume
anything about whether the above example accurately reflects the
types that were discussed earlier.
My reading of the standard is that the two types are clearly *not*
compatible. (Irrelevantly, they're very likely to have the same
representation.)
I'll refer to the N3096 draft of C23, section 6.2.7. I don't think
other editions give different answers.
Two complete struct types *with the same tag* are compatible if
they meet certain requirements. These types have different tags,
"point" and "_tag", so those requirements are irrelevant here.
Furthermore, two structure, union, or enumerated types declared in
separate translation units are compatible in the following cases:
- both are declared without tags and they fulfill the requirements
above;
— both have the same tag and are completed somewhere in their
respective translation units and they fulfill the requirements above;
— both have the same tag and at least one of the two types is not
completed in its translation unit.
None of these three bullet points applies to types with different tags
*or* to types with different member names (a, b vs. x, y).
Otherwise, the structure, union, or enumerated types are
incompatible.
Conclusion: They're incompatible.
Two regular users commented on *some* pair of types and disagreed
on whether they're compatible. I won't comment here on who was
correct, because I don't know whether they were talking about the
types quoted above.
[...]
Practically, if you need two translation units to use compatible struct
types, you should define the type in a shared header. That guarantees
(assuming no nasty tricks are played before the #include directive) that
the types have the same tag, and the same member names and types in the
same order.
-- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.comvoid Void(void) { Void(); } /* The recursive call of the void */