While C++11 standard says this about reinterpreting std::complex<double>
as double
s:
For any pointer to an element of an array of
complex<T>
namedp
and any valid array indexi
,reinterpret_cast<T*>(p)[2*i]
is the real part of the complex numberp[i]
, andreinterpret_cast<T*>(p)[2*i + 1]
is the imaginary part of the complex numberp[i]
The intent of this requirement is to preserve binary compatibility between the C++ library complex number types and the C language complex number types (and arrays thereof), which have an identical object representation requirement.
Is it true for the backward reinterpreting? I mean is it safe to perform something like this: std::complex<double> *cppComplexArray = reinterpret_cast<std::complex<double> *>(cDoublesArray)
where cDoublesArray
have a type of double *
and even length 2 * n
? What are potential pitfalls if its length will be odd (2 * n + 1
)?
Is it true for the backward reinterpreting? I mean is it safe to perform something like this:
std::complex<double> *cppComplexArray = reinterpret_cast<std::complex<double> *>(cDoublesArray)
Casting/initialization itself is safe, using the result as-if pointing to an element of an array of std::complex<double>
is not.
When cDoublesArray
(or the array-to-pointer conversion applied to it, if cDoublesArray
denotes an array of double
s) points to the first element of an array of double
s, reinterpret_cast<std::complex<double>*>(cDoublesArray)
does the same (has the same value).
Using an expression of type std::complex<double>*
whose value «pointer to an object of type double
» (like reinterpret_cast<std::complex<double>*>(cDoublesArray)
or cppComplexArray
) in pointer arithmetic (e.g. cppComplexArray + 0
) would violate [expr.add]/6:
For addition or subtraction, if the expressions
P
orQ
have type “pointer to cvT
”, whereT
and the array element type are not similar, the behavior is undefined.
(T
is std::complex<double>
, array element type is double
here, and they are not similar)
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With