Is casting and accessing an array of correct alignment and size to a not constructed Trivial Type undefined behaviour?

Viewed 80

Is the following code well defined?

struct S { int x; };
alignas(alignof(S)) char c_arr[sizeof(S)];
S *s_ptr = (S*)c_arr;
s_ptr->x = 5; // UB or not UB?

Note: S is purposfully defined as a Trivial Type.

Would the situation change if we made the type none trivial by adding a constructor that just sets X to some arbitrary value without calling it through placement new?

This question is different from this question because it does not use malloc and does ask also about none trivial types.

1 Answers

Is the following code well defined?

No. It violates the so called strict aliasing rule.

You must launder the pointer:

S *s_ptr = std::launder(reinterpret_cast<S*>(c_arr));
s_ptr->x = 5; // not UB

Prior to acceptance of proposal P0593R6, laundering would not have been sufficient. Instead, it used to be necessary to explicitly create the object using placement-new. That is still necessary when the reinterepreted type is not an "implicit-lifetime-type".

Related