I wish to call fftw's in-place real-to-complex transform function, which has the following signature:
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
);
The documentation says that I should indicate that I wish to perform an in-place transform by passing in aliasing pointers for the in
and out
parameters.
QUESTION: How can in
and out
alias without violating strict aliasing rules?
I am open to GCC-specific extensions (i.e., using union
s to do type-punning, even though the standard declares this to be undefined behavior). Even if this extension is permitted, a union cannot contain dynamically-sized arrays (which is a must in this applications - I do not know the transform length in advance). Does anyone have any ideas? Thanks in advance.
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.