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 doubles 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 doubles 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.