Search code examples
c++arrayslanguage-lawyercomplex-numbers

reinterpreting array of doubles as array of std::complex<double>


While C++11 standard says this about reinterpreting std::complex<double> as doubles:

For any pointer to an element of an array of complex<T> named p and any valid array index i, reinterpret_cast<T*>(p)[2*i] is the real part of the complex number p[i], and reinterpret_cast<T*>(p)[2*i + 1] is the imaginary part of the complex number p[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)?


Solution

  • 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 doubles) points to the first element of an array of doubles, 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 or Q have type “pointer to cv T”, where T 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)