Reputation: 9203
Suppose I have 2 types A
and B
with same size and I have two variables
A a = ... ; // Initialized to some constant of type A
B b;
If I copy the contents of a
to b
using something like -
assert(sizeof(A) == sizeof(B));
size_t t;
for( t=0; t < sizeof(A); t++){
((char*)&b)[t] = ((char*)&a)[t];
}
Does this break strict aliasing rules of C?
I know casting a pointer to char*
and reading it is not UB but I am concerned about both the derefences involved in the assignment.
If this is not UB, can this be a valid way for type punning?
Upvotes: 10
Views: 190
Reputation: 81247
In cases where the destination has a declared type, there is no problem, but in cases where the destination is known only via pointer the Standard is ambiguous. According to the absolutely horribly written 6.5p6, copying data using memcpy
or memmove
, or "as an array of character type" [whatever that means] will cause the Effective Type of the source to be applied to the destination. The Standard doesn't specify what one must do to copy a sequence of bytes without the operation being regarded as copying an "array of character type".
Upvotes: 1
Reputation:
This code does not violate aliasing rules. From the latest draft (n1570), §6.5 section 7:
An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
— a type compatible with the effective type of the object,
— a qualified version of a type compatible with the effective type of the object,
— a type that is the signed or unsigned type corresponding to the effective type of the object,
— a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
— a character type
(emphasis mine)
I am concerned about both the derefences involved in the assignment.
These dereferences are accessing the stored value using a character type.
Of course, you could still trigger undefined behavior if the representation of your A
is not a valid representation for B
.
Upvotes: 5