当我查看Linux内核代码时,找到以下代码:
struct thread_info {
struct task_struct *task;
struct exec_domain *exec_domain;
unsigned long flags;
__u32 status;
__u32 cpu;
int preempt_count;
mm_segment_t addr_limit;
struct restart_block restart_block;
void __user *sysenter_return;
unsigned long previous_esp;
__u8 supervisor_stack[0];
};
注意最后一个变量“supervisor_stack”,它是一个零长度数组,它的用法是什么?提前谢谢!
答案 0 :(得分:38)
这是灵活阵列成员的C99前版本,由GCC作为扩展提供。
C99的方法是用空括号定义灵活的数组成员
__u8 supervisor_stack[];
它用于存储数量与结构不连续的数据。内存以
的形式分配struct foo *ptr = malloc(sizeof *ptr + whatever_is_needed);
在6.7.2.1的第18段中,标准(草案N1570)描述了它们:
作为一种特殊情况,具有多个命名成员的结构的最后一个元素可以 有一个不完整的数组类型;这被称为灵活的阵列成员。在大多数情况下, 灵活的数组成员被忽略。特别是,结构的大小就像是 省略了灵活的数组成员,除了它可能有更多的尾随填充 遗漏意味着。但是,当
.
(或->
)运算符具有左操作数时 (指向)具有灵活数组成员和右操作数名称的结构 成员,它的行为好像该成员被替换为最长的数组(具有相同的 元素类型)不会使结构大于被访问的对象;该 数组的偏移量应保持灵活阵列成员的偏移量,即使这会有所不同 从替换阵列的。如果此数组没有元素,则表现得好像 它有一个元素,但如果有任何尝试访问它,行为是未定义的 元素或生成一个经过它的指针。
答案 1 :(得分:10)
通常的C hack声明可以称为变量长度数组(在分配时定义大小的地方
示例:
struct line {
int length;
char contents[0];
};
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
通过这种方式,您可以对数据进行结构定义,这也可以存储数组长度以实现明显的便利性,但您不会受到通常与结构相关联的固定大小的限制
取自here的示例(此处还有更多信息)