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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3016107/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:38:37  来源:igfitidea点击:

What is tagged structure initialization syntax?

csyntaxlinux-kernel

提问by httpinterpret

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,
};

This declaration uses the standard C tagged structure initialization syntax.

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

Can someone elaborate?

有人可以详细说明吗?

回答by AnT

When you use aggregate initializers (initializers in {}) in the "traditional" ANSI C language (C89/90), you have to supply an individual initializer for each structure member in order, beginning with the first. For example

当您{}在“传统”ANSI C 语言 (C89/90) 中使用聚合初始化程序(初始化程序 in )时,您必须按顺序为每个结构成员提供一个单独的初始化程序,从第一个开始。例如

struct S { int a, b, c, d; };

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

You are not required to specify initializers for all members, i.e. you can stop at any time (remaining members will be zero-initialized).

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

If for some reason you only cared to explicitly initialize the third member of the structure, you had to supply "dummy" explicit initializers for the first and the second members (just to get to the desired third)

如果由于某种原因您只关心显式初始化结构的第三个成员,则必须为第一个和第二个成员提供“虚拟”显式初始化器(只是为了获得所需的第三个)

/* We only care to explicitly initialize `s.c` */
struct S s = { 0, 0, 3 };
/* but we have to explicitly initialize `s.a` and `s.b` as well */

or abandon specific initialization entirely (likely replacing it with generic = { 0 }) and use a subsequent assignment to specific members

或完全放弃特定的初始化(可能用 generic 替换它= { 0 })并使用后续分配给特定成员

struct S s = { 0 };
s.c = 3;

One notable benefit of this assignment-based approach is that it is independent from the position of member cin the declaration of struct S.

这种基于任务的方法的一个显着的好处是,它是独立于成员的位置c中的声明struct S

The new specification of C language (C99) allows you to use "tagged" initializers by supplying the desired member name within the {}

C 语言 (C99) 的新规范允许您通过在 {}

struct S s = { .c = 3 };

That way you only explicitly initialize the desired member(s) (and have the compiler to zero-initialize the rest). This not only saves you some typing but also makes the aggregate initializers independent from the order in which the members are specified in the struct type declaration.

这样,您只需显式初始化所需的成员(并让编译器对其余成员进行零初始化)。这不仅为您节省了一些输入,而且使聚合初始值设定项独立于结构类型声明中指定成员的顺序。

Aggregate initializers, as you probably know, can be used with arrays, too. And C99 supports "tagged" initialization with arrays as well. How the "tags" look in case of an array is illustrated by the following example

您可能知道,聚合初始值设定项也可以与数组一起使用。C99 也支持使用数组进行“标记”初始化。以下示例说明了“标签”在数组情况下的外观

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

It is worth noting one more time that C language continues to stick to the "all or nothing" approach to aggregate initialization: if you specify an explicit initializer for just one (or some) members of a struct or an array, the whole aggregate gets initialized, and the members without explicit initializers get zero-initialized.

再次值得注意的是,C 语言继续坚持“全有或全无”的方法来进行聚合初始化:如果仅为结构或数组的一个(或一些)成员指定显式初始化程序,则整个聚合将得到初始化,并且没有显式初始化器的成员被初始化为零。

回答by httpinterpret

You're using the names of the members of the structure to initialise the structure. i.e. each member initialisation is "tagged" with that member's name.

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

回答by Guy Avraham

Another benefit worth mention regarding this type of initialization is that it allows the reordering of structure members, which in some cases, can make performance improvements by, for instance ,placing pointers to frequently accessed members in the same hardware cache line.

关于这种类型的初始化,另一个值得一提的好处是它允许重新排序结构成员,在某些情况下,这可以提高性能,例如,将指向频繁访问的成员的指针放在同一硬件缓存行中。