在struct中初始化const数组

时间:2017-06-04 08:19:46

标签: c

#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修饰符似乎无济于事。

2 个答案:

答案 0 :(得分:1)

以符合标准的方式做到这一点是不可能的。

由于它为constconst char data[6];必须初始化为可用,并且只能初始化静态(没有初始化程序的静态对象会自动归零),使用字符串文字,或使用大括号括起初始化列表。您无法使用指针或其他数组对其进行初始化。

如果我是你,我会删除const.data在初始化后不应该更改的文档,然后使用memcpy对其进行初始化。

(结构成员const在我看来并不能很好地工作。它有效地阻止你能够拥有初始化函数,而且C ++通过使用特殊语言来解决问题支持其构造函数,如果const成员是数组,问题仍然存在。

答案 1 :(得分:1)

可以这样做,费用为>=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⇒从{{1直接到x)。其他人(gcc我在看着你)似乎无法实现这一点。

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