[英]Is FlatBuffers C++ reinterpret_cast access actually undefined behavior? Is it practically OK to do that?
[英]Is this reinterpret_cast OK to do
我是EE,而不是代码专家,所以请在这里请耐心等待。
我正在使用Embarcadero C ++ Builder(XE3)。
我有一个FFT算法,它对复数进行了大量的操作。 我发现如果我绕过Embarcadero的复杂数学库,并在我自己的代码中进行所有计算,我的FFT运行速度将快4.5倍。 这里显示的4个操作都需要过多的时间。
#include <dinkumware\complex>
#define ComplexD std::complex<double>
ComplexD X, Y, Z, FFTInput[1024];
double x, y;
Z = X * Y;
x = X.real();
y = X.imag();
Z = ComplexD(x,y);
用我自己的交叉乘法替换乘法将我的执行时间减半。 然而,我关心的是我访问输入数组的实部和虚部的方式。 我这样做:
double *Input;
Input = reinterpret_cast<double *>(FFTInput);
// Then these statements are equivalent.
x = FFTInput[n].real();
y = FFTInput[n].imag();
x = Input[2*n];
y = Input[2*n+1];
这样做可以将执行时间再缩短一半,但我不知道这种reinterpret_cast是否是明智之举。 我可以将输入数组更改为两个双精度而不是复数,但我在许多程序中使用此FFT并且不想重写所有内容。
这个reinterpret_cast好吗,还是我有内存问题? 另外,有没有办法让Embarcadero复杂的数学函数运行得更快? 最后,虽然它对我来说不是非常重要,但是这个reinterpret_cast是否可移植?
这是允许的。 虽然这不是标准报价,但cppreference有这样的说法:
对于任何指向复数
p
和任何有效数组索引i
的元素的指针,reinterpret_cast<T*>(p)[2*i]
是复数p[i]
的实部,并且reinterpret_cast<T*>(p)[2*i + 1]
是复数p[i]
的虚部。
我很快就会从实际标准中寻找报价。
从这里它在页面底部说:
对于任何复数z,
reinterpret_cast<T(&)[2]>(z)[0]
是z的实部,而reinterpret_cast<T(&)[2]>(z)[1]
是虚部的虚部。 ž。对于任何指向复数p和任何有效数组索引i的元素的指针,
reinterpret_cast<T*>(p)[2*i]
是复数p [i]的实部,并且reinterpret_cast<T*>(p)[2*i + 1]
是复数p [i]的虚部。 (自C ++ 11以来)这些要求实质上限制了std :: complex的三个特化中的每一个的实现,以声明两个且仅有两个类型为value_type的非静态数据成员,它们具有相同的成员访问权限,分别保存实部和虚部。
所以你所做的就是保证在C ++ 11中工作,但在此之前不行。 它可能仍然适用于您的库的实现,但您需要检查您的库的实现没有按照第三段定义任何更多的非静态数据成员。
如果没有使用std::complex
的定义并且知道编译器如何实现这个定义,我们就无法回答这个问题。 实际上, reinterpret_case
是否正确取决于std::complex
类型的内存布局。 据我所知,这里没有任何指定。 所以它肯定不便携。 所以答案是:它可能适用于某些编译器/架构,而不适用于其他一些编译器/架构。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.