typedef struct cmplx {
float re;
float im;
} cmplx_t;
浮点数组可以安全地转换为这种复杂类型吗?
一样:
float s[SIZE*2];
cmplx_t* c = (cmplx_t*) s; // ??
结构体与浮点指针的关系如何?
cmplx_t c[SIZE];
float* c = (float*) c; // ??
原题
可以通过cmplx_t *
访问float
数组吗?
C标准中的语言似乎允许这样做。首先,我们必须考虑将自动转换为指针的s
转换为cmplx_t *
。C 2018 6.3.2.3 7部分定义了转换,只要对齐是正确的。该标准并不保证结构体的对齐要求最多是其成员的最严格的对齐要求,但这是典型的,因此在普通的C实现中定义了转换。
那么我们必须考虑混叠规则。C 2018 6.5 7说:
对象的存储值只能通过左值表达式访问,且左值表达式必须具有以下类型之一:
—与对象的有效类型兼容的类型,
—与对象的有效类型兼容的类型的限定版本,
—与对象的有效类型相对应的有符号或无符号类型,
—有符号或无符号类型,对应于对象有效类型的限定版本,
—在其成员中包含上述类型之一的聚合或联合类型(递归地包括子聚合或包含联合的成员),或
—一个字符类型。
由于c
指向定义为float
对象的内存,因此float
是"与对象的有效类型兼容的类型",而*c
是"在其成员中包含上述类型之一的聚合或联合类型"。因此,*c
、c->re
和c->im
应该是混叠规则允许的访问。
C标准也没有规定cmplx_t
的布局在re
成员之后紧接im
成员。C实现允许在成员之间和结构的末尾插入填充。但是,对于相同类型的成员,没有理由这样做,典型的C实现也不会这样做。因此,在普通的C实现中,c->re
和c->im
应该访问float
数组的所需元素,c[i].re
和c[i].im
也应该访问。
添加问题可以通过float *
访问cmplx_t
的数组吗?
C标准没有定义这种行为。对于类型为cmplx_t
的对象,float
不是上面列出的任何类型。