什么是标记结构初始化语法?

struct file_operations scull_fops = { .owner = THIS_MODULE, .llseek = scull_llseek, .read = scull_read, .write = scull_write, .ioctl = scull_ioctl, .open = scull_open, .release = scull_release, }; 

该声明使用标准C标记的结构初始化语法。

有人可以详细说明吗?

当您使用“传统”ANSI C语言(C89 / 90)中的聚合初始值设定项( {}中的初始值设定项)时,必须按顺序为每个结构成员提供单独的初始值设定项。 例如

 struct S { int a, b, c, d; }; struct S s = { 1, 2, 3, 4 }; /* 1 for `sa`, 2 for `sb` and so on... */ 

您不需要为所有成员指定初始值设定项,即您可以随时停止(其余成员将被初始化)。

如果由于某种原因你只关心显式地初​​始化结构的第三个成员,那么你必须为第一个和第二个成员提供“虚拟”显式初始化器(只是为了达到期望的第三个成员)

 /* We only care to explicitly initialize `sc` */ struct S s = { 0, 0, 3 }; /* but we have to explicitly initialize `sa` and `sb` as well */ 

或完全放弃特定的初始化(可能将其replace为generic = { 0 } ),并使用后续分配给特定成员

 struct S s = { 0 }; sc = 3; 

这种基于赋值的方法的一个显着优点是它独立于struct S声明中成员c的位置。

C语言的新规范(C99)允许您通过在{}提供所需的成员名称来使用“标记”

 struct S s = { .c = 3 }; 

这样你只显式地初始化所需的成员(并且让编译器将其余部分初始化)。 这不仅可以节省一些input,还可以使聚合初始化程序独立于在结构体types声明中指定成员的顺序。

如你所知,集合初始化器也可以和数组一起使用。 而且C99也支持对数组进行“标记”初始化。 以下示例说明了如何在数组中使用“标签”

 int a[10] = { [5] = 3 }; /* `a[5]` is initialized with 3, the rest of `a` is zero-initialized */ 

再次值得注意的是,C语言继续坚持“全部或全部”的方法来聚合初始化:如果你为结构体或数组中的一个(或某些)成员指定了一个显式的初始化方法,那么整个聚合体会得到初始化,没有显式初始化的成员得到零初始化。

您正在使用结构成员的名称来初始化结构。 即每个成员的初始化都是用该成员的名字“标记”的。

关于这种types的初始化值得一提的是,它允许对结构成员进行重新sorting,在某些情况下,可以通过将指针指向经常访问的成员放在同一个硬件高速caching行中来提高性能。