Reputation: 3930
Does the following code violate strict aliasing?
int a = 0;
*((int *)((char *)&a)) = 1;
Why not? because we end up dereferencing the pointer of int a
using int *
which is legit
Why yes? because we cast the char *
to int *
and dereferencing it (the int *
), which seems as a strict aliasing violation
Upvotes: 1
Views: 82
Reputation: 140445
The strict aliasing rules do not care about intermediate casts. They only care about the type of the pointer ultimately used to access an object, and the original type of the object itself (technically its "effective type", but that's not important right now).
In your example code, you take the address of an int
. The result has type int *
. You cast that pointer to char *
, you cast it again to int *
, and only then do you dereference it. The type of the pointer used in the access is int *
and the type of the object pointed to is int
, so the strict aliasing rules have no problem.
You are correct that the strict aliasing rules are asymmetric with respect to char
, but that only matters when either the type of the object itself is char
or the type of the pointer used in the access is char
:
char x[sizeof(int)] = { 0 };
*(int *)x = 1; // undefined behavior
int y = 1234;
*(char *)y = 0; // valid; value of y becomes unspecified
Theoretically, a cast between two pointer types can lose information, but not when casting from some other type to char *
and back again. Also, this is only relevant on computers that you are very unlikely to encounter nowadays. I can't actually remember an example.
Upvotes: 2
Reputation: 134286
No, it is not a violation.
because we cast the
char *
toint *
You are missing the part the the char *
you mentioned was actually an int *
. Thus, finally the access to an int
type is made via a pointer to int
- this is perfectly valid.
Upvotes: 1
Reputation: 223689
This code is valid. It is allowed to convert between two object pointer types and back provided there are not alignment issues, and converting to a char *
is explicitly allowed to access an objects representation (i.e. read the individual bytes).
Section 6.3.2.3p7 of the C standard states:
A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.
Since you covert from int *
to char *
then back to int *
, there are no strict aliasing violations here.
Upvotes: 1