结构体标签化

4
在C语言中,我希望能够在结构体内部标记特定的位置。例如:
struct test {
    char name[20];

    position:
    int x;
    int y;
};

这样我就可以做到:
struct test srs[2];
memcpy(&srs[1].position, &srs[0].position, sizeof(test) - offsetof(test, position));

将 srs[0] 的位置复制到 srs[1]。

我尝试过将 position 声明为没有任何字节的类型,但这也没有起作用:

struct test {
    char name[20];

    void position; //unsigned position: 0; doesn't work either
    int x;
    int y;
};

我知道我可以将x和y嵌入到另一个名为position的结构体中:

struct test {
    char name[20];

    struct {
        int x;
        int y;
    } position;
};

或者直接使用x属性的位置:

struct test srs[2];
memcpy(&srs[1].x, &srs[0].x, sizeof(test) - offsetof(test, x));

然而我在想是否有一种方法可以实现我最初的想法。

2个回答

10
struct test {
    char name[20];

    char position[0];
    int x;
    int y;
};

在网络协议代码中,长度为0的数组曾经非常流行。


正是我所需要的!你甚至可以更进一步地使用:typedef char struct_label[0]; - CHRIS
5
+1,很好的例子,需要补充说明的是这不是C语言,而是GNU扩展。 - ouah

5

使用C11的另一种解决方案是使用匿名结构体与匿名联合:

struct test {
    char name[20];

    union {
        int position;
        struct {
            int x;
            int y;
        };
    };
};
position的地址是name成员之后的结构成员的地址。
我仅展示它是为了展示,自然的解决方案是只需在您问题的第一个结构声明中获取成员x的地址。

这是一个不错的解决方案,但是将位置声明为整数看起来有些误导。 - CHRIS
@CHRIS 它被声明为 int,因此它与 x 成员具有相同的类型,因此明确指出 position 的添加不会增加 union 的大小。另一方面,类型并不重要,因为我们不取成员的值而是其地址。 - ouah
是的,但是该值仍可被使用,与真实标签不同。我想const int可能更合适,但如果后来有其他人维护代码,则其目的乍一看仍不清楚。 - CHRIS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接