Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is tag and name equality required for struct/union compatibility?

Tags:

c

struct

c99

C99 standard has the following language in section 6.2.7.1:

two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements: If one is declared with a tag, the other shall be declared with the same tag. If both are complete types, then the following additional requirements apply: there shall be a one-to-one correspondence between their members such that each pair of corresponding members are declared with compatible types, and such that if one member of a corresponding pair is declared with a name, the other member is declared with the same name. For two structures, corresponding members shall be declared in the same order. For two structures or unions, corresponding bit-fields shall have the same widths. For two enumerations, corresponding members shall have the same values. (emphasis added)

In particular, this rule makes these two structs with identical layout incompatible, because their tags and member names do not match:

struct x_type {
    int x;
};

struct y_type { // << Different tag
    int y;      // << Different member name
};

It is easy to understand why member types and their declaration order must be the same. However, it is not clear why tags and member names need to match as well, even though they do not influence binary layout of struct?

like image 472
Sergey Kalinichenko Avatar asked Dec 18 '15 17:12

Sergey Kalinichenko


1 Answers

The text you quote isn't talking about layout-compatible types, it's talking about types that are the same type. That rule is how C defines whether two definitions of a type are valid re-definitions of the same type.

In your example you're damn right that x_type and y_type aren't compatible, because they certainly don't describe the same type! If they were compatible it would mean that calling void foo(struct x_type*) with an argument of type struct y_type* would be valid, which is certainly not the intention.

The text you quote and the following paragraph are the C equivalent of the C++ ODR, and requiring the tags and member names to be the same is similar to this wording from [basic.def.odr]:

Given such an entity named D defined in more than one translation unit, then

— each definition of D shall consist of the same sequence of tokens; and
— in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3), [...]

like image 118
Jonathan Wakely Avatar answered Oct 19 '22 16:10

Jonathan Wakely