在不违反严格的别名规则的情况下调用FFTW的就地实数到复杂变换

Sum*_*ood 8 c++ gcc strict-aliasing fftw c++17

我希望调用fftw的就地实到复杂转换函数,该函数具有以下签名:

fftw_plan fftw_plan_dft_r2c_1d(
    int n,             // transform length
    double* in,        // pointer to input array
    fftw_complex* out, // pointer to output array
    unsigned flags     // flags
);
Run Code Online (Sandbox Code Playgroud)

该文档说,我应该指出我希望通过传递inout参数的别名指针来执行就地转换。


问:怎样才能inout不违反严格别名规则的别名?


我对特定于GCC的扩展union持开放态度(即,即使标准将其声明为未定义行为,也可以使用s进行类型校正)。即使允许此扩展,联合也不能包含动态大小的数组(在此应用程序中这是必须的-我事先不知道变换长度)。有人有什么想法吗?提前致谢。

ixS*_*Sci 2

根据此链接, fftw_complex内容如下typedef

\n\n
typedef double fftw_complex[2];\n
Run Code Online (Sandbox Code Playgroud)\n\n

根据 C++20 之前的规则,可能会因此fftw_complex*产生别名( [basic.lval]p8.6 ):double*

\n\n
\n

如果程序尝试通过以下类型之一以外的泛左值访问对象的存储值,则行为未定义:
\n ...
\n \xe2\x80\x94聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(递归地包括子聚合或包含联合的元素或非静态数据成员)

\n
\n\n

数组是一个聚合,我们的数组包含doubles,因此允许为double指针添加别名。因此,fftw_plan_dft_r2c_1d函数中不会发生严格的别名规则违规,您可以安全地使用它。

\n\n

但请注意,该段落已从 C++20 标准中删除,并且有人争论是否也应将其从 C 标准中删除。但由于它尚未被删除,并且 GCC 和 clang 实际上尊重它,我想可以安全地假设该行为不会随着 C++20 实现而改变。据我所知,MSVC 根本没有利用 SAR。

\n