嵌套结构中的灵活数组成员 [英] flexible array member in a nested struct

查看:38
本文介绍了嵌套结构中的灵活数组成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在嵌套结构中具有灵活的数组成员是有效的 C 代码吗?那么我下面的示例代码是否能保证在正常编译器下按预期工作?

Is it valid C code to have flexible array members inside nested structs? So is my sample code below guarenteed to work as expected with a sane compiler?

#include <stdio.h>
#include <stdlib.h>

struct d {
    char c;
    int ns[];
};

struct c {
    struct d d;
};

struct b {
    struct c c;
};

struct a {
    int n;
    struct b b;
};

int main() {
    const int n = 10;
    struct a *pa = malloc(sizeof(*pa) + n * sizeof(pa->b.c.d.ns[0]));
    pa->n = n;
    pa->b.c.d.c = 1;
    for (int i = 0; i < n; ++i) {
        pa->b.c.d.ns[i] = i;
    }
    for (int i = 0; i < n; ++i) {
        printf("%d\n", pa->b.c.d.ns[i] + pa->b.c.d.c);
    }
    free(pa);
}

推荐答案

它不符合标准.我不确定它在实践中的可靠性.

It's not valid per the standard. I'm not sure how reliable it is in practice.

C11(ISO/IEC 9899:2011)第 6.7.2.1.3 节说明如下(重点是我的):

C11 (ISO/IEC 9899:2011), §6.7.2.1.3 says the following (emphasis mine):

结构或联合不应包含不完整或函数类型的成员(因此,结构不应包含自身的实例,但可以包含指向自身实例的指针),除了最后一个成员具有多个命名成员的结构可能具有不完整的数组类型;这样的结构(以及任何包含,可能递归地包含这种结构的成员的联合)不应是结构的成员或数组的元素.

A structure or union shall not contain a member with incomplete or function type (hence, a structure shall not contain an instance of itself, but may contain a pointer to an instance of itself), except that the last member of a structure with more than one named member may have incomplete array type; such a structure (and any union containing, possibly recursively, a member that is such a structure) shall not be a member of a structure or an element of an array.

稍后,第 6.7.2.1.18 节澄清了上述内容指的是灵活数组成员 (FAM):

Later on, §6.7.2.1.18 clarifies that the above is referring to flexible array members (FAMs):

作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这称为灵活数组成员.

As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member.

根据一些快速实验,即使 struct 嵌套,GCC 和 Clang 都添加了正确对齐 FAM 所需的尾随填充,并且仅对 FAM 是其他结构或数组的成员的结构发出警告如果 -Wpedantic 被传递,所以把它当作一个标志,如果你愿意,它可能会工作:).不过感觉有点hackish.

From some quick experimentation, GCC and Clang both add the trailing padding required to align the FAM properly even when the struct is nested, and only warn about structures with FAMs being members of other structures or arrays if -Wpedantic is passed, so take that as a sign that it'll probably work if you will :). It feels a bit hackish though.

请注意,除了最后之外,在任何地方使用 FAM 可能都没有意义.如果你这样做

Note that it probably wouldn't make sense to have the FAM anywhere but at the end. If you do

struct e {
    struct d d;
    int n;
} e;

,那么 e.d.ns[0]e.n 很可能在内存中重叠.

, then e.d.ns[0] and e.n are likely to overlap in memory.

这篇关于嵌套结构中的灵活数组成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆