Re:The semver trick (2019)
by josephcsible on Saturday August 01, 2020 @01:51PM
(#24022472)
Doesn't the "common initial sequence" rule imply that structs with the same members must be the same, even within a translation unit? If they didn't, wouldn't putting them both in a union and accessing through the other one not work, even though the standard requires it to work?
Re:The semver trick (2019)
by forrestthewoods on Saturday August 01, 2020 @03:04PM
(#24023018)
What is a tag in C?
Re:The semver trick (2019)
by formerly_proven on Saturday August 01, 2020 @03:09PM
(#24023067)
The name of a struct ("struct foo", the tag is "foo").
In C, two structs with different tags in the same translation unit are indeed incompatible. (That includes two structs with no tag that look the same, because, effectively, each has some internal, machine-generated tag.)
Within the same translation unit, looking the same is not a consideration at all; it's all based on the tag symbol.
Between translation units, two complete struct types that are exactly the same (same members, of the same type, in the same order, with the same names, and other details like bitfield configuration) are compatible are if they both have the same tag.
But they are also compatible if neither has a tag: and in that case, they would be incompatible if they were in the same translation unit.
Basically, two machine-generated tags for anonymous structs are considered equivalent if they are in different translation units, in which case compatibility is purely down to structural equivalence.
In practice, C compilers do not police struct tags at all between translation units; you can get away with it if the same object is known as "struct point { double x, y; }" and "struct pointe { double x, y; }" in another translation units. You can even change the member names, for that matter.
You will run aground with a C++ compiler, though, due to type safe linkage which pulls in class names.
FFI implementations obviously don't care about any of this. If I'm declaring an FFI type that is to be compatible with the C "struct stat" in a Lisp, so I can call the stat function, these concepts have gone out the window. The memory layout compatibility is all that matters: correct sizes, alignments, conversions.