Technically it works and you can use it. As pointed in comments the relevant part of the ANSI standard is:
6.7.2.1: Structure and union specifiers
... A pointer to a
structure object, suitably converted, points to its initial member (or if that member is a
bit-field, then to the unit in which it resides), and vice versa. There may be unnamed
padding within a structure object, but not at its beginning.
The strict aliasing does not matter in this case.
Strict aliasing rule specifies in which circumstances a value of some type can be changed by changing a value of another type. The main interest of this rule are scalar types like int
and float
. In your particular case it is evident that by changing a member of a struct (unsigned char []
) you change the whole structure and vice versa.
This case is covered by the 5th subcase of the strict aliasing rule. I quote the whole part for the sake of completeness:
6.5 Expressions, p.7
An object shall have its stored value accessed only by an lvalue expression that has one of
the following types (The intent of this list is to specify those circumstances in which an object may or may not be aliased):
— 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
where the definition of aggegate types is in:
6.2.5 Types, p.21
Arithmetic types and pointer types are collectively called scalar types. Array and
structure types are collectively called aggregate types.