嵌套结构中的灵活数组成员

xiver77

在嵌套结构中具有灵活的数组成员是否有效的C代码?那么,下面的示例代码是否可以保证正常运行时可以正常工作?

#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);
}
增白剂

按照标准无效。我不确定它在实践中是否可靠。

C11(ISO / IEC 9899:2011)§6.7.2.1.3表示以下内容(强调我的意思):

结构或联合不得包含具有不完整或函数类型的成员(因此,结构不应包含其自身的实例,但可以包含指向其自身的实例的指针),除非结构的最后一个成员具有大于一个命名成员可能具有不完整的数组类型;这样的结构(以及可能包含递归关系的任何并集的任何并集)都不应该是结构的成员或数组的元素。

稍后,第6.7.2.1.18节阐明了以上内容是指灵活数组成员(FAM):

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

经过一些快速的实验,GCC和Clang都添加了正确对齐FAM所需的尾随填充,即使在struct嵌套也是如此,并且仅FAM成为其他结构或数组的成员时才发出警告-Wpedantic,因此将其表示为如果可能的话,它可能会起作用:)。不过,它感觉有点破旧。

请注意,除了最后,在任何地方都可以使用FAM。如果你这样做

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

,则e.d.ns[0]e.n可能在内存中重叠。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

什么是结构中的灵活数组成员?

具有灵活数组成员的结构的“数组”

未命名结构的灵活数组成员

具有灵活数组成员的结构的大小

GCC与Clang复制结构灵活数组成员

C ++中的灵活数组成员的可移植仿真?

没有命名成员的GCC错误结构灵活数组成员

如何均匀地分配具有灵活数组成员的结构体数组?

具有灵活数组成员的结构的数组如何表现?

使用数组并在结构中分配内存(灵活的数组成员)

当我对结构进行浅拷贝时,灵活数组成员没有被复制

是否允许返回具有灵活数组成员的结构?

比较指向具有灵活数组成员的结构的 2 个指针

如何初始化具有 unint_t 作为灵活数组成员的结构?

C ++“替换”为具有灵活数组成员的结构

dart:ffi 中结构的数组成员

具有灵活数组成员的结构和具有指针成员的结构之间的区别

为什么使用灵活的数组成员进行的结构初始化无效但对于固定大小的数组成员却有效?

联合会支持灵活的数组成员吗?

使用灵活的数组成员实现堆栈

灵活的数组成员,以访问联合原始字节

应该使用宏而不是灵活的数组成员吗?

灵活数组成员的静态初始化

了解 malloc 和灵活的数组成员

是在CA中访问结构中的数组成员访问值或地址?

与具有柔性数组成员的匿名结构联合

具有数组成员的结构

初始化固定的C数组成员结构

返回具有数组成员的本地结构