In "Structure and union members" part of the C standard, an analogue of the following code is mentioned to be valid: (ISO/IEC 9899:201x, 6.5.2.3.9 EXAMPLE 3)
#include<stdio.h>
union point {
struct {
int value;
} x;
struct {
int value;
} y;
};
int main() {
union point p;
p.x.value = 1;
printf("%d\n", p.y.value);
}
That's because of the following section of the draft:
One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the union is visible. Tw o structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.
Is this also valid according to the standard?
#include<stdio.h>
union point {
int x;
int y;
};
int main() {
union point p;
p.x = 1;
printf("%d\n", p.y);
}
Is there some sort of paragraph in the specification that guarantees the object representation is fully dependent on the type of the object and thus this is fine?
Would it also work with more complex types? (like structs or unions?)
To extend the question, given:
union first {
int a;
char b;
};
union second {
int a;
char b;
float c;
};
Is there any way to write a pure function with the signature:
union second convert(union first input)
that follows the standard and doesn't require us to remember which variant is stored in union first and which maps the matching union first member onto the union second members?
Accessing an object as the type that it is is not type punning.
Given
union point { int x; int y; };andunion point p;, if a value is stored inp.xand then accessed withp.y, the value is that ofp.y, per C 2018 6.5.2.3 3. Note 99 makes it clear that the value ofp.yis the value represented by the bytes in the union interpreted as the type ofp.y:Since the bytes in the union are those that were used to store a value in
p.x, of typeint, then when interpreted as typeintforp.y, they represent the same value.C 2018 6.2.6 specifies how types are represented, and paragraph 2 says:
It is not clear what you mean here. If you have some object that is a
union first, then it is aunion first. Objects are regions of memory whose contents may represent values. C accesses objects (for writing or reading), and it operates on values. There is no operation to convert an object to another object. Values can be converted. Objects can be interpreted as one type or another. If you have questions about interpreting the region of memory forming one object using another type, you need to be clearer about what you are attempting to do and the circumstances.