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

标签 c syntax linux-kernel

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.

有人可以详细说明吗?

最佳答案

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

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... */

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

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

/* 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 */

或者完全放弃特定的初始化(可能用通用的 = { 0 } 代替它)并使用对特定成员的后续赋值

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

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

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

中提供所需的成员名称来使用“标记的”初始值设定项
struct S s = { .c = 3 };

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

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

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

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

关于c - 什么是标记结构初始化语法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3016107/

相关文章:

c - C语言中的上溢和下溢

C复数和printf

c# - 静态方法声明中的 "this"是什么意思?

linux - sigreturn 如何在 SECCOMP_SET_MODE_STRICT 中阻止除 SIGKILL 和 SIGSTOP 之外的所有信号?

c - 使用消息队列的全双工通信,连续打印消息

c - 使用 g_malloc0 后释放内存

javascript - 有人可以向我解释 redux 形式验证中的这个逻辑吗?

syntax - f(s::String) 和 f(::String) 的区别

linux-kernel - Linux 内核中的 IPsec - 如何弄清楚发生了什么

java - 如何获取在 Kubernetes 节点上运行的 Pod 的历史记录?