> Structurally identical types will be considered the same type in GCC 15 and Clang later in 2025 thanks to a rule change
Beware that only tagged unions are considered the same type under the new rule, provided they have the same structrure and the same tag.
The List(T) macro should be changed to generate a different tag for each different T. Which is trivial (with ##) for simple one-word types, but impossible for even mildly complex ones like pointers to char (strings).
Of course you can force yourself to typedef any type before using it in a List, but it looses much of its versatility. Example:
The latter has an identifier, bar; the former doesn't. The standard uses tag to refer to the identifier name, if any, in an enum, struct, or union declaration.
I've always called "tag" the id that optionally follows struct/union/enum. Is it the wrong word? Some specs call it "name", but "unnamed union" sounds dangerously similar to "anonymous union", which is a different concept, namely (no pun!) an unnamed member of an outer struct or union whose submembers can be accessed as if they belong in the outer one. E.g.
struct {
struct {
int m;
}; // no name: anonymous
struct s;
s.m = 1;
Beware that only tagged unions are considered the same type under the new rule, provided they have the same structrure and the same tag.
The List(T) macro should be changed to generate a different tag for each different T. Which is trivial (with ##) for simple one-word types, but impossible for even mildly complex ones like pointers to char (strings).
Of course you can force yourself to typedef any type before using it in a List, but it looses much of its versatility. Example: