This question may seem trivial but I am confused about it. Suppose I have an array of doubles with can accommodate 2*N doubles(The data is stored such that we can visualize it as a matrix of shape (N,2)). In memory double Complex number is represented as two doubles. Can I cast the data as array of N double complex? Below is an example of what I am trying to do. I compiles fine but just wanted to know if this is valid?
#include <complex.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
int N = 1000;
double * A = malloc(sizeof(double)*2*N);
for (int i=0; i<2*N; i){
A[i] = 1.0;
}
double complex * B = (double complex *) A ;
printf("%f I*%f",creal(B[1]),cimag(B[1]));
free(A);
return 0;
}
Thank very much in advance
CodePudding user response:
C 2018 6.2.5 13 says:
Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex number.
This guarantees that you could use memcpy
to copy the bytes representing an array of 2 N double
objects to the bytes of an array of N complex double
objects, or vice-versa, and get the naturally expected results: Because they have the same representation in memory, and the C standard supports reading and updating the bytes that represent objects through memcpy
or other character-copying mechanisms, this will reproduce the values.
It is less clear this means you can alias the same memory using the different types which is what you do by converting a pointer and dereferencing in the new type. Formally, this does not conform to the aliasing rules in C 2018 6.5 7. However, in discussing another case in which the standard imposes requirements that representations be identical, 6.2.5 9, for corresponding signed and unsigned integer types, non-normative note 41 in the standard says:
The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.
This may be interpreted to mean the authors of the standard wanted us to be able to alias things that were required to have the same representation and alignment requirements but that the committee did not get around to writing formal rules for that.
In my experience with various compilers, they will support this particular aliasing. Optimizations will be made assuming, for example, that int
and float
types do not alias the same memory but not that “array reshaping” (reinterpreting a multidimensional array as an array of other dimensions) will not occur, including this treatment of complex double
objects and arrays of double
. If you are writing academic software to study some scientific models and the risk of being wrong about this interpretation of the C standard is that wrong answers might be produced, this might be a risk you are willing to take. If you are writing safety-critical software, you should not rely on this interpretation without assertions from the compiler developers.