In practice the backward reinterpreting will probably work most of the time, in view of the strong constraints of the forward reinterpreting impose (see on cppreference, std::complex
, implementation notes).
However, I'm not totally sure that such backward reinterpreting would in always work in theory:
- Let's imagine an absurd and hypothetical implementation of a complex library that would maintain a list of addresses of active complex objects (e.g. for debugging purpose). This (probably static) list would be maintained by the complex constructor and destructor.
- Every complex operation in this library would verify if its operands are in the list.
- While forward reinterpreting would work (the complex objects were well constructed and its parts can be used as doubles), the backward reinterpretation would not work (e.g. despite a compatible layout, you would reinterpret as complex a pair of doubles and if you'd perform any complex operation on them, it would fail since the complex was not properly constructed, i.e. its address is not in the list).
As said, this complex library would probably be a stupid idea. But such a library could be implemented and compliant with the standard specs. This is sufficient to prove that there is no reverse guarantee in theory.
The last point of your question is easier and more obvious to answer, supposing we would have an implementation where the reverse reinterpretation works. The missing last column would lead to an access of a part that is out of bounds. This would therfore lead to UB.
Additional readings: This working paper of the standard committee requests a general convertability feature that would generalize the bahavior of reinterpret_cast
on complex
for other types. It explains the complex case in section 4 and the special handling required from the compiler to make it work if complex is not itself implemented by an array.
std::complex
itself is a well-behaved enough type... maybe. Otherwise C++ has some dark corners in its object model (that vary as the years go by). It may be ill-formed C++17 and valid C++20. I'd hate to try and prove it formally though. – BragicppComplexArray
in pointer arithmetic will violate [expr.add]/6 – Remittance