Что такое синтаксис инициализации теговой структуры? - PullRequest
43 голосов
/ 10 июня 2010
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 инициализация теговой структуры синтаксис.

Может кто-нибудь уточнить?

Ответы [ 3 ]

79 голосов
/ 10 июня 2010

Когда вы используете агрегатные инициализаторы (инициализаторы в {}) на «традиционном» языке 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;

Одним заметным преимуществом этого подхода на основе присвоения является то, что он не зависит от позиции члена c в объявлении struct S.

Новая спецификация языка 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 продолжает придерживаться подхода «все или ничего» для агрегированной инициализации: если вы укажете явный инициализатор только для одного (или нескольких) членов структуры или массива, вся совокупность инициализируется, а члены без явных инициализаторов инициализируются нулями.

4 голосов
/ 10 июня 2010

Вы используете имена членов структуры для инициализации структуры.т. е. инициализация каждого члена «помечена» именем этого члена.

1 голос
/ 16 октября 2017

Еще одно преимущество, заслуживающее упоминания в отношении этого типа инициализации, заключается в том, что он позволяет переупорядочивать элементы структуры, что в некоторых случаях может повысить производительность, например, путем размещения указателей на часто используемые элементы в одной строке аппаратного кэша.

...