#define LENGTH 6
typedef char data_t[LENGTH];
struct foo {
    const data_t data;
    ...
}
...
void bar(data_t data) {
    printf("%.6s\n", data);
    struct foo myfoo = {*data};
    printf("%.6s\n", foo.data);
}

我正在尝试使用此结构直接保存我感兴趣的数据sizeof(foo) == 6+the rest,而不是sizeof(foo) == sizeof(void*)+the rest。但是我找不到用foo初始化data_t类型的结构的方法。我认为也许我可以从字段中删除const修饰符并使用memcpy,但我喜欢额外的安全性和清晰度。

我没有任何编译错误,但是当我运行代码时,我得到了
123456
1??

因此,我认为该副本无法正常工作。

这是用于arduino(或类似设备)的,所以我试图将其保留为非常可移植的代码。

只是不可能吗?

编辑:删除const字段上的data_t修饰符似乎无济于事。

最佳答案

可以这样做,但要花费一些>=0

typedef struct
{
    char c[LENGTH];
} data_t; // this struct is freely copyable

struct foo
{
    const data_t data; // but this data member is not
    int what;
};

void foo (char* x) {
    data_t d;                         // declare freely copyable struct instance
    memcpy(d.c, x, sizeof(d.c));      // memcpy it
    struct foo foo = { d, 42 };       // initialise struct instance with const member
    ...
};

一些编译器(例如clang)甚至能够优化冗余复制(从xd.c,然后从dfoo.data⇒从xfoo.data)。其他人(我正在看你的gcc)似乎无法实现这一目标。

如果将指针传递给data_t而不是直接的char指针,则将不需要此额外的memcpy步骤。 OTOH为了访问char中的foo数组,您需要另一级别的成员访问权限(.data.c而不是.data;这没有运行时成本)。

关于c - 在结构内部初始化const数组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44352117/

10-11 15:32
查看更多