What's the purpose of layout-compatible types?

2020-06-17 04:35发布

问题:

The standard defines when two types are layout-compatible. But, I don't see anywhere in the standard what the consequences are when two types are layout-compatible. It seems that layout-compatible is a definition which is not used anywhere.

What is the purpose of layout-compatible?

Note: Supposedly, it could mean that the types have the same layout (offsetof is the same for each corresponding member), so for example, for trivially copyable types, underlying bytes can be copied between them. But I don't see something like this in the standard.

回答1:

The standard does define one specific case where layout compatibility matters: in unions. If two members are layout-compatible, and one of them is the active union member, then you may access that object through pointers/references to any layout-compatible member of that union. This is a consequence of the "common initial sequence" rule.



回答2:

The Standard makes no attempt to mandate that all implementations be suitable for all purposes. Consequently, quality implementations intended to be suitable for purposes beyond those for which the Standard require support will generally need to extend the semantics of the language. One of the simplest and most useful ways they can do this is by saying that in some circumstances where portions of the Standard define or imply the behavior of some action but another part says an overlapping category of actions invoke UB, they will process the behavior as defined or implied by the former parts. On many compilers, for example, there is an option (typically enabled with a -fno-strict-aliasing flag) to say that any program whose behavior would be defined in the absence of type-access rules will be processed in that fashion, even if those rules would say the program invokes UB.

While there are relatively few situations where the fact that two structures are layout-compatible would cause behavior to be defined by the Standard when it otherwise wouldn't, there are many situations where it would imply how an implementation must behave in the absence of those type-access rules (by making it essentially impossible for an implementation to do anything else). For example, if structure types T1 and T2 are layout compatible, that would suggest that if a pointer to a T1 is converted to a T2*, any operation upon a member of the structure using the latter pointer will access the corresponding member of the T1 object.

Because not all programs need such abilities, the Standard does not require that all implementations provide them. On the other hand, implementations that are suitable for low-level programming will provide means by which parts of the code that are designed to handle one type can be used to handle layout-compatible types interchangeably, whether the Standard requires them to or not (implementations that don't would simply be limited to uses other than low-level programming).

I think the Standard would be enormously improved by officially recognizing categories of implementations that are suitable for low-level programming and others that make no claim to be, rather than trying to define a single set of behavior for all implementations. Nonetheless, defining concepts like "layout compatibility" greatly improves the range of constructs that will be portable among implementations that are suitable for low-level programming.