Calling FFTW's in-place real-to-complex transform without violating strict aliasing rules
I'll challenge the premise: Don't worry about strict aliasing too much.
Make an array of double
and pass a pointer to it to in
. reinterpret_cast
the pointer to fftw_complex *
and pass it to out
.
Read the resulting double
s from this array (as pairs of real and imaginary components of complex numbers).
Yes, fftw_plan_dft_r2c_1d
will probably break strict aliasing under the hood if called this way.
But since it's in a separate translation unit, and caller doesn't violate strict aliasing, your compiler has no way to tell if strict aliasing was indeed violated.
fftw_complex
is essentially a struct fftw_complex {double re, im;};
, so everything should work just fine.
For extra safety you can add:
static_assert(sizeof(fftw_complex) == 2 * sizeof(double) && alignof(fftw_complex) <= alignof(double));
According to this link fftw_complex
is the following typedef
:
typedef double fftw_complex[2];
And by the pre-C++20 rules fftw_complex*
may alias double*
because of this ([basic.lval]p8.6):
If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:
...
— an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic data members (including, recursively, an element or non-static data member of a subaggregate or contained union)
Array is an aggregate and our array contains double
s thus it is allowed to alias a double
pointer. Hence, no strict aliasing rule violation happens in the fftw_plan_dft_r2c_1d
function and you can safely use it.
Note, however, that this paragraph is removed from the C++20 standard and it is debated that it should be removed from the C standard as well. But since it is not removed yet and GCC & clang actually respect it I guess it is safe to assume that the behavior won't change with C++20 implementation. And MSVC, to my knowledge, doesn't take advantage of SAR at all.