我有这个结构:
typedef struct V2f {
float x, y; } V2f;
在我的机器上(64位Lubuntu 15.10)我可以使用此功能扫描它而没有任何问题:
#include <stdbool.h>
#include <stdio.h>
bool scan_struct_as_arr(void *dst, int n, size_t sz, char *format) {
for(int i = 0; i < n; ++i) {
if(!scanf(format, (char *) dst + i * sz)) {
fputs("Failed to scan struct as an array", stderr);
return false; } }
return true; }
这种行为可移植多少,为什么?
如果只使用大小为4或8的变量,是否可以信任此代码?
答案 0 :(得分:3)
一般来说,这不安全或不便携:
C.11 6.7.2.1结构和联合说明符
- 结构或联合对象的每个非位字段成员在定义的实现中对齐 适合其类型的方式。
- 在结构对象内,非位字段成员和位域中的单位 驻留的地址按声明的顺序增加。 ......可能有人没有透露姓名 在结构对象中填充,但不在其开头。
醇>
给定的实现可能会决定对于结构,每个其他浮点数应该与前一个浮点数相差16位,而对于数组,它会使它们保持连续。
更便携的解决方案是传递地址,无论是作为数组还是可变参数:
bool scan_addr_array (void *addrs[], size_t N, const char *fmt);
bool scan_addr_va (const char *fmt, ... /* NULL terminated */);
答案 1 :(得分:1)
不安全,不可移植:从struct V2f *
转换为void *
然后转换为char *
会调用未定义的行为。