大小为零的指针数组是什么意思?
What does it mean to have a zero sized array of pointers?
我在 linux 内核源代码 (net/ipv4/fib_trie.c
)-
中看到了一个看起来像这样的 struct
的定义
struct key_vector {
t_key key;
unsigned char pos; /* 2log(KEYLENGTH) bits needed */
unsigned char bits; /* 2log(KEYLENGTH) bits needed */
unsigned char slen;
union {
/* This list pointer if valid if (pos | bits) == 0 (LEAF) */
struct hlist_head leaf;
/* This array is valid if (pos | bits) > 0 (TNODE) */
struct key_vector __rcu *tnode[0];
};
};
上面tnode
的定义是什么意思?我写了一个示例代码来理解和打印看起来像 -
struct s {
union {
int i;
int *pi[0];
};
};
int main()
{
struct s s1;
s1.i = 0x12345678;
printf("sizeof(s1): %lu, s1.i: %x, s1.pi: %p, s1.*pi: %p\n", sizeof(s1), s1.i, s1.pi[0], s1.pi);
}
其输出为-
sizeof(s1): 8, s1.i: 12345678, s1.pi: 0x7ffc12345678, s1.*pi: 0x7ffc2824add0
我不确定我是否理解这一点。
这是一种常见的做法,称为“struct hack”或灵活的数组成员。为结构分配内存时,添加额外的 space。然后可以使用结构末尾的数组成员访问额外的 space 。从 C99 开始,您可以完全忽略大小。
在批准 C89 之前,许多编译器会将结构中的 someType member[someConst];
之类的声明解释为将“下一项偏移量”推进到 someType
对齐要求的倍数,关联具有该偏移量的符号 member
,将 someConst
解释为无符号数,然后将“下一个成员偏移量”推进 someConst * sizeof someType
。他们会以这种方式行事 ,而不考虑 someConst
是否为零。因为一些程序依赖于编译器以这种方式处理零长度数组声明,但委员会的一些成员不想要求所有编译器都支持它们,所以标准的作者选择说实现可能支持零长度数组或不是,在他们闲暇时,前提是当提供任何利用零大小数组的程序时,他们至少会发出一个诊断(程序员在使用有效支持该构造的实现时可以在闲暇时忽略)。
我在 linux 内核源代码 (net/ipv4/fib_trie.c
)-
struct
的定义
struct key_vector {
t_key key;
unsigned char pos; /* 2log(KEYLENGTH) bits needed */
unsigned char bits; /* 2log(KEYLENGTH) bits needed */
unsigned char slen;
union {
/* This list pointer if valid if (pos | bits) == 0 (LEAF) */
struct hlist_head leaf;
/* This array is valid if (pos | bits) > 0 (TNODE) */
struct key_vector __rcu *tnode[0];
};
};
上面tnode
的定义是什么意思?我写了一个示例代码来理解和打印看起来像 -
struct s {
union {
int i;
int *pi[0];
};
};
int main()
{
struct s s1;
s1.i = 0x12345678;
printf("sizeof(s1): %lu, s1.i: %x, s1.pi: %p, s1.*pi: %p\n", sizeof(s1), s1.i, s1.pi[0], s1.pi);
}
其输出为-
sizeof(s1): 8, s1.i: 12345678, s1.pi: 0x7ffc12345678, s1.*pi: 0x7ffc2824add0
我不确定我是否理解这一点。
这是一种常见的做法,称为“struct hack”或灵活的数组成员。为结构分配内存时,添加额外的 space。然后可以使用结构末尾的数组成员访问额外的 space 。从 C99 开始,您可以完全忽略大小。
在批准 C89 之前,许多编译器会将结构中的 someType member[someConst];
之类的声明解释为将“下一项偏移量”推进到 someType
对齐要求的倍数,关联具有该偏移量的符号 member
,将 someConst
解释为无符号数,然后将“下一个成员偏移量”推进 someConst * sizeof someType
。他们会以这种方式行事 ,而不考虑 someConst
是否为零。因为一些程序依赖于编译器以这种方式处理零长度数组声明,但委员会的一些成员不想要求所有编译器都支持它们,所以标准的作者选择说实现可能支持零长度数组或不是,在他们闲暇时,前提是当提供任何利用零大小数组的程序时,他们至少会发出一个诊断(程序员在使用有效支持该构造的实现时可以在闲暇时忽略)。