web-dev-qa-db-fra.com

Quelle est la syntaxe d'initialisation de la structure marquée?

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

Cette déclaration utilise la syntaxe d'initialisation de la structure étiquetée C Standard C.

Quelqu'un peut-il élaborer?

43
httpinterpret

Lorsque vous utilisez des initialiseurs agrégés (initialisateurs dans {}) Dans le langage ANSI C (traditionnel "(C89/90), vous devez fournir un initialisateur individuel pour chaque membre de la structure afin de commencer par le premier. Par exemple

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

Vous n'êtes pas obligé de spécifier des initialisateurs pour tous les membres, c'est-à-dire que vous pouvez vous arrêter à tout moment (les membres restants seront initialisés zéro).

Si, pour une raison quelconque, vous ne souciez que d'initialiser explicitement le troisième membre de la structure, vous deviez fournir des initialiseurs explicites "factices" pour les premier et les seconds membres (juste pour vous rendre au troisième souhaité).

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

ou abandonner entièrement une initialisation spécifique (le remplaçant probablement avec générique = { 0 }) et utiliser une affectation ultérieure à des membres spécifiques

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

Un avantage notable de cette approche basée sur la mission est qu'il est indépendant de la position de membre c dans la déclaration de struct S.

La nouvelle spécification de la langue C (C99) vous permet d'utiliser des initialiseurs "marqués" en fournissant le nom de membre souhaité dans le {}

struct S s = { .c = 3 };

De cette façon, vous initialisez uniquement explicitement l'élément (s) souhaité (et avez-vous le compilateur à zéro-initialiser le reste). Cela vous évite non seulement de taper, mais rend également les initialisateurs d'agrégats indépendants de l'ordre dans lequel les membres sont spécifiés dans la déclaration de type STR.

Les initialisateurs agrégés, comme vous le savez probablement, peuvent également être utilisés avec des tableaux. Et C99 prend également en charge l'initialisation "marquée" avec des tableaux. Comment les "balises" regardent en cas d'une matrice illustrée par l'exemple suivant

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

Il convient de noter une fois de plus que c langage C continue de s'en tenir à l'approche "Tout ou rien" de l'initialisation globale: si vous spécifiez un initialisateur explicite pour un (ou certains) membres d'une structure ou d'une matrice, tout l'agrégat obtient initialisé et les membres sans initialisateurs explicites obtiennent zéro initialisée.

80
AnT

Vous utilisez les noms des membres de la structure pour initialiser la structure. c'est-à-dire que chaque initialisation de membre est "marquée" avec le nom de ce membre.

4
user23743

Un autre avantage mérite d'être mentionné sur ce type d'initialisation est qu'il permet de réorganiser les membres de la structure, ce qui peut, dans certains cas, peut apporter des améliorations de performance par, par exemple, de placer des pointeurs à des membres fréquemment accédés dans la même ligne de cache matérielle.

1
Guy Avraham