The text you are quoting does not speak of types compatible with layouts, it speaks of types of the same type . This rule is how C determines whether two type definitions are valid repeated definitions of the same type.
In your example, you are damn right that x_type and y_type are incompatible because they, of course, do not describe the same type! If they were compatible, this would mean that calling void foo(struct x_type*) with an argument of type struct y_type* would be valid, which, of course, is not the intention.
The text you specify and the next paragraph are the C-equivalent of ODR C ++ and require that the tags and names of the participants are the same, similar to this wording from [basic.def.odr]:
Given such an object named D , defined in several translation units, then
- each definition of D should consist of the same sequence of tokens; and
- in each definition of D corresponding names scanned in accordance with 3.4 must refer to the object defined in definition D , or must refer to the same object after overload resolution (13.3) and after matching, partial type specialization (14.8.3) , [...]
source share