扫描与数组相同类型的N个成员的结构是否安全?

时间:2015-12-30 19:00:05

标签: c arrays pointers struct scanf

我有这个结构:

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的变量,是否可以信任此代码?

2 个答案:

答案 0 :(得分:3)

一般来说,这不安全或不便携:

  

C.11 6.7.2.1结构和联合说明符

     
      
  1. 结构或联合对象的每个非位字段成员在定义的实现中对齐   适合其类型的方式。
  2.   
  3. 在结构对象内,非位字段成员和位域中的单位   驻留的地址按声明的顺序增加。 ......可能有人没有透露姓名   在结构对象中填充,但不在其开头。
  4.   

给定的实现可能会决定对于结构,每个其他浮点数应该与前一个浮点数相差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 *会调用未定义的行为。