将float *强制转换为std :: complex <float> * </float>是否合法

时间:2014-04-21 13:58:51

标签: c++ c++11 language-lawyer

N3797 26.4 [complex.numbers] 说明了如何将std::complex<T>*投射到T*

  

4此外,如果a是cv std::complex<T>*类型的表达式,并且表达式a[i]已经为整数表达式i定义良好,那么:
    - reinterpret_cast<cv T*>(a)[2*i]应指定a[i]和/的真实部分     - reinterpret_cast<cv T*>(a)[2*i + 1]应指定a[i]的虚部。

这(或标准的其他一些措辞)是否意味着我可以reinterpret_cast反过来?我可以这样做:

    float * pf;
    std::complex<float>* pc = reinterpret_cast<std::complex<float>*>(pf);
    pc[i].real();

早上好在下面指出,我必须确保pf的对齐适合std::complex<float>。可以假设这是照顾的。

2 个答案:

答案 0 :(得分:3)

不,该条款没有这样的保证。

现在,在实践中,最常见的问题是对齐:但即便如此也是如此。

第二个问题涉及严格别名,其中编译器可以假设分配为double的内存不会被涉及指向其他类型的指针的任何操作修改(char除外)。上面的限制是另一种方式(complex分配的指针可能不会假设double*没有指向它的数据),但不是你想要的方向。同样,这是相对模糊的,但编译器可以使用它来重新排序代码中的写入。

但是,它通常会起作用。更常见的是,如果你对齐它,并且你的编译器不使用严格的别名假设:然而,即使这样,它也是标准的未定义行为。

答案 1 :(得分:1)

它没有相反的工作方式。 std::complex<float>是内存中的两个连续float,正如标准允许您做的那样,但是您有一个指向单个浮点值的指针并将其转换为指向一个应该包含两个浮子的结构。即使您有两个浮点数,标准也不能保证它,因此reinterpret_cast指向该方向的指针是非法的。