Что такое теговый синтаксис инициализации структуры?

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 отмеченный синтаксис инициализации структуры.

Кто-то может уточнить?

43
задан Tim Post 10 June 2010 в 17:34
поделиться

2 ответа

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

Таким образом, вы явно инициализируете только нужный член (члены) (а компилятор обнуляет остальные). Это не только экономит ввод текста, но и делает агрегатные инициализаторы независимыми от порядка, в котором члены указаны в объявлении типа struct.

Агрегатные инициализаторы, как вы, вероятно, знаете, можно использовать и для массивов. И C99 поддерживает "тегированную" инициализацию с массивами. Как выглядят "метки" в случае массива, показано на следующем примере

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

Стоит еще раз отметить, что язык Си продолжает придерживаться подхода "все или ничего" к агрегатной инициализации: если вы указываете явный инициализатор только для одного (или некоторых) членов структуры или массива, инициализируется весь агрегат, а члены без явных инициализаторов получают нулевую инициализацию.

79
ответ дан 26 November 2019 в 22:50
поделиться

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

4
ответ дан 26 November 2019 в 22:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: