【发布时间】:2014-03-06 09:32:10
【问题描述】:
我注意到开源项目中经常使用结构体末尾的空数组:
typedef struct A
{
......
void *arr[];
} A;
我想知道这是 C 标准吗?还是只适用于 gcc 编译器?
【问题讨论】:
标签: c
我注意到开源项目中经常使用结构体末尾的空数组:
typedef struct A
{
......
void *arr[];
} A;
我想知道这是 C 标准吗?还是只适用于 gcc 编译器?
【问题讨论】:
标签: c
从 C99 开始,它现在是 C 标准。 C99 之前的编译器可能不支持它。旧方法是声明一个 1 元素数组,并为此调整分配大小。
新方法:
typedef struct A
{
......
void *arr[];
} A;
int slots = 3;
A* myA = malloc(sizeof(A) + slots*sizeof(void*));
myA->arr[2] = foo;
老办法:
typedef struct A
{
......
void *arr[1];
} A;
int slots = 3;
A* myA = malloc(sizeof(A) + (slots-1)*sizeof(void*));
myA->arr[2] = foo;
【讨论】:
sizeof(void*)==4,那么arr[1]将在arr[0]之后的四个字节,无论A如何填充。
6.7.2.1 的标准(草案 N1570)18 规定:
作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能 数组类型不完整;这称为灵活数组成员。在大多数情况下, 灵活的数组成员被忽略。特别是,结构的大小就像 灵活的数组成员被省略,除了它可能有更多的尾随填充比 遗漏将意味着。然而,当一个 . (或 ->)运算符有一个左操作数,即 (指向)具有灵活数组成员和正确操作数名称的结构 成员,它的行为就好像该成员被替换为最长的数组(具有相同的 元素类型)不会使结构大于被访问的对象;这 数组的偏移量应保持灵活数组成员的偏移量,即使这会有所不同 从替换阵列的那个。如果这个数组没有元素,它的行为就像 它有一个元素,但如果尝试访问该元素,则行为未定义 元素或生成一个越过它的指针。
【讨论】: