Based on your comments, it seems that you want to perform a bona fide conversion, that is, create a separate new, separate value of a different type. This is a completely different matter than reinterpretation, for example, an introduction to your question suggests what you wanted. In particular, you set variables declared as follows:
uint8x16_t a; uint8x8x2_t b;
and you want to know how to set the value of b so that it is in a sense equivalent to the value of a .
Speaking in C language:
The strict rule of aliases ( C2011 6.5 / 7 ) says:
The object must have a stored value, accessible only with the value of the lvalue expression, which has one of the following types:
- a type compatible with an efficient object type, [...]
- a type of aggregate or combination that includes one of the above types among its members [...] or
- character type.
(An additional emphasis has been added. Other listed options include different, qualified, and different versions of an effective object type or compatible types that are not relevant here.)
Note that these provisions never interfere with access to the value of a , including the value of the member, through the variable a and similarly for b . But do not overlook the use of the term "effective type" - this is where things can be called up in slightly different circumstances. More on this later.
Using a join
C, of ββcourse, allows you to do the conversion through an intermediate union , or you can rely on b as a member of the union in the first place to remove the "intermediate" part:
union { uint8x16_t x1; uint8x8_2_t x2; } temp; temp.x1 = a; b = temp.x2;
Using a type pointer (to create a UB)
However, although this is not uncommon, C does not allow you to enter a pun through a pointer:
Here you access the value of a , whose effective type is uint8x16_t , through an lvalue of type uint8x8x2_t . Please note that this prohibition is not prohibited, and even, I would not say, dereferencing - it reads the dereferenced value to apply the side effect of the = operator.
Using memcpy()
Now, what about memcpy() ? That's where it gets interesting. C allows access to stored values ββof a and b through character type lvalues, and although its arguments are declared to be of type void * , this is the only plausible interpretation of how memcpy() works. Of course, his description characterizes him as copying characters. Therefore there is nothing wrong with doing
memcpy(&b, &a, sizeof a);
By doing this, you can freely access the value of b through the variable b , as already mentioned. There are aspects that may be problematic in a more general context, but there is no UB.
However , compare this with an externally similar situation in which you want to put the converted value in a space with dynamic allocation:
uint8x8x2_t *c = malloc(sizeof(*c)); memcpy(c, &a, sizeof a);
What could be wrong? There is nothing wrong with that, but here you have UB, if after that you try to access the value *c . What for? because the memory for which the c point does not have a declared type, therefore its effective type is the effective type of what was stored in it (if it has an effective type), including if this value was copied into it via memcpy() ( C2011 6.5 / 6 ). As a result, the object to which c is of the effective type uint8x16_t after the copy, while the expression *c is of the type uint8x8x2_t ; the strictest aliasing rule says that access to this object through this lvalue calls UB.