Linux 结构体中零长度数组的目的是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11733981/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the purpose of a zero length array in a struct?
提问by Derui Si
When I'm looking the Linux kernel code, found the below code:
当我查看 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];
};
Notice that the last variable "supervisor_stack", it is a zero length array, what is the usage of it? Thanks in advance!
注意最后一个变量“supervisor_stack”,它是一个零长度数组,它的用途是什么?提前致谢!
采纳答案by Daniel Fischer
It's the pre-C99 version of a flexible array member, offered by GCC as an extension.
它是灵活数组成员的 C99 之前版本,由 GCC 作为扩展提供。
The C99 way is to define the flexible array member with empty brackets,
C99的方式是用空括号定义灵活的数组成员,
__u8 supervisor_stack[];
It's used to store data whose amount is not constant contiguous to the struct. Memory is allocated in the form
它用于存储数量与结构不连续的数据。内存分配的形式
struct foo *ptr = malloc(sizeof *ptr + whatever_is_needed);
In paragraph 18 of 6.7.2.1, the standard (draft N1570) describes them:
在 6.7.2.1 的第 18 段中,标准(草案 N1570)对它们进行了描述:
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. In most situations, the flexible array member is ignored. In particular, the size of the structure is as if the flexible array member were omitted except that it may have more trailing padding than the omission would imply. However, when a
.
(or->
) operator has a left operand that is (a pointer to) a structure with a flexible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed; the offset of the array shall remain that of the flexible array member, even if this would differ from that of the replacement array. If this array would have no elements, it behaves as if it had one element but the behavior is undefined if any attempt is made to access that element or to generate a pointer one past it.
作为一种特殊情况,具有多个命名成员的结构的最后一个元素可能具有不完整的数组类型;这称为灵活数组成员。在大多数情况下,灵活的数组成员会被忽略。特别是,结构的大小就像省略了灵活的阵列成员,只是它可能具有比省略所暗示的更多的尾随填充。然而,当一个
.
(或->
) 运算符有一个左操作数,它是(指向)具有灵活数组成员的结构,右操作数命名该成员,它的行为就好像该成员被替换为最长的数组(具有相同的元素类型),不会使结构大于被访问的对象;数组的偏移量应保持灵活数组成员的偏移量,即使这与替换数组的偏移量不同。如果这个数组没有元素,它的行为就好像它只有一个元素,但如果尝试访问该元素或生成一个超过它的指针,则行为是未定义的。
回答by Naps62
It's a common C hack to declare what can be called a variable length-array (where you define the size at allocation time
声明什么可以称为可变长度数组(在分配时定义大小)是一种常见的 C hack
Example:
例子:
struct line {
int length;
char contents[0];
};
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
This way you have a structure definition of your data, which also stores the array length for obvious convecience purposes, but you're not constrained by the fixed size that is usually associated with a struct
这样,您就有了数据的结构定义,它还存储了数组长度以方便使用,但您不受通常与结构关联的固定大小的限制
Example taken from here(also more info in there)
从这里获取的示例 (还有更多信息)