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

标签 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 的变量,人们可以信任此代码吗?

最佳答案

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

C.11 6.7.2.1 Structure and union specifiers

  1. Each non-bit-field member of a structure or union object is aligned in an implementation defined manner appropriate to its type.
  2. Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. ... There may be unnamed padding within a structure object, but not at its beginning.

给定的实现可能会决定,对于结构体,每个其他浮点应该与前一个浮点相距 16 位,而对于数组,它使它们保持连续。

更可移植的解决方案是仅以数组或变量参数的形式传入地址:

bool scan_addr_array (void *addrs[], size_t N, const char *fmt);
bool scan_addr_va (const char *fmt, ... /* NULL terminated */);

关于c - 扫描与数组类型相同的 N 个成员的结构是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34535523/

相关文章:

c++ - 如何分配内存块并将其放入Cache?

php - 如何在 PHP 中将一行存储到数组中并回显数组的某个值?

c++ - 如何使用指针检查数组中的某个位置是否被修改

c++ - 我可以在引用返回类型中返回一个指针吗?

c++ - 为什么结构数组的 memset 会改变程序行为?

c - 如何修改已传递给 C 函数的指针?

c - 当指针类型不同时如何产生编译错误?

c - C 中的链表/指针

c - 我如何操作这个表?

javascript - 通过组合这两个其他数组来生成此数组