Reputation: 8610
typedef struct cmplx {
float re;
float im;
} cmplx_t;
Can float array be safely cast to this complex type?
Like so:
float s[SIZE*2];
cmplx_t* c = (cmplx_t*) s; // ??
What about the vice-versa, struct to float pointer?
cmplx_t c[SIZE];
float* c = (float*) c; // ??
Upvotes: 3
Views: 436
Reputation: 223633
Can an array of float
be accessed through a cmplx_t *
?
The language in the C standard appears to permit this. First, we have to consider the conversion of s
, which is automatically converted to a pointer, to cmplx_t *
. C 2018 6.3.2.3 7 partially defines the conversion as long as the alignment is correct. The standard does not guarantee that the alignment requirement of a structure is at most the strictest alignment requirement of its members, but this is typical, so the conversion is defined in ordinary C implementations.
Then we have to consider the aliasing rule. C 2018 6.5 7 says:
An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
— a type compatible with the effective type of the object,
— a qualified version of a type compatible with the effective type of the object,
— a type that is the signed or unsigned type corresponding to the effective type of the object,
— a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
— a character type.
Since c
points to memory that was defined as float
objects, float
is “a type compatible with the effective type of the object”, and *c
is “an aggregate or union type that includes one of the aforementioned types among its members.” Therefore, *c
, c->re
, and c->im
ought to be accesses permitted by the aliasing rule.
The C standard also does not specify that the layout of cmplx_t
has the im
member immediately following the re
member. C implementations are allowed to insert padding between members and at the end of the structure. However, with members of the same type, there is no reason to do so, and typical C implementations do not. So, in ordinary C implementations, c->re
and c->im
should access the desired elements of the float
array, and so should c[i].re
and c[i].im
.
Can an array of cmplx_t
be accessed through a float *
.
The C standard does not define the behavior of attempting this. For an object of type cmplx_t
, float
is not any of the types listed above.
Upvotes: 6