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.
Can someone elaborate?
An optional identifier, called a "tag," gives the name of the structure type and can be used in subsequent references to the structure type. A variable of that structure type holds the entire sequence defined by that type. Structures in C are similar to the types known as "records" in other languages.
An initializer for a structure is a brace-enclosed comma-separated list of values, and for a union, a brace-enclosed single value. The initializer is preceded by an equal sign ( = ).
A union can have a constructor to initialize any of its members. A union without a constructor can be initialized with another union of the same type, with an expression of the type of the first member of the union, or with an initializer (enclosed in braces) of the type of the first member of the union.
Designated initialization is an extension of aggregate initialization and empowers you to directly initialize the members of a class type using their names. Designated initialization is a special case of aggregate initialization.
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
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
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 c
in the declaration of struct S
.
The new specification of C language (C99) allows you to use "tagged" initializers by supplying the desired member name within the {}
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With