Designated Initializers en C

Une lecture sur Stackoverflow m’a fait découvrir des possibilités très intéressantes quant à l’initialisation des structures et des tableaux. Le C ANSI impose que l’ordre des champs dans l’initialisation d’une structure ou dans un tableau soit le même que l’ordre des éléments de cette structure ou de ce tableau. Par exemple, dans le code suivant :

int tableau[] = {0, 1, 3, 42};

les valeurs sont données dans l’ordre des indices (0 à l’indice 0, 1 à l’indice 1, 3 à l’indice 2 et 42 à l’indice 3). Impossible de définir uniquement la valeur 42 à l’indice 3.

Le C99 offre un mécanisme plus complexe pour spécifier les indices des tableaux ou les champs des structures auxquels appliquer les valeurs d’initialisation. Ce sont les designated initializers. GCC offre un mécanisme complémentaire pour autoriser l’initialisation d’un tableau grâce à une plage . Plutôt qu’un long discours, voici un joli code exemple !

#include <stdio.h>
#include <string.h>

typedef struct
{
    int entier;
    float flottant;
    short court;
} sData;

int main()
{
    unsigned int i;

    // Standard C99
    char dataC99[] = { [0] = 'a', 'c', [6] = 'b'};
    sData structC99 = {.flottant = 3.1415, .court = 42,  .entier = 65000};

    // Extension GNU
    char dataGNU[] = { [0 ... 3 ] = 'a', 'c', [6] = 'b'};

    puts("C99");
    for(i=0; i < sizeof(dataC99); putchar(dataC99[i++]) )
        ;
    printf("\nEntier = %d\tFlottant = %f\tCourt = %d", structC99.entier, structC99.flottant, structC99.court);

    puts("\n\nGNU");
    for(i=0; i < sizeof(dataGNU); putchar(dataGNU[i++]) )
        ;

    return 0;
}

J’utilise les options indispensables options -Wall -Wextra, ainsi que la contraignante -pedantic pour avoir le maximum d’information sur la compatibilité du code. Enfin, je spécifie que le code doit être compilé en C99 grâce à l’option -std=c99. Avec CodeBlocks sous Windows XP (utilisant le portage de GCC), le compilateur n’émet qu’un seul warning, qui correspond bien à l’extension GNU :

d:\…\developpez.c|21|warning: ISO C forbids specifying range of elements to initialize

Si on remplace -std=c99 par -ansi, on aura en plus toute une tripotée de warnings comme celui-ci :

d:\…\developpez.c|16|warning: ISO C90 forbids specifying subobject to initialize

Exemple d’application directe ? On peut initialiser un tableau  à une valeur particulière autre que zéro en toute simplicité :

int array[1024] = {[0 ... 1023] = 5};

Pour plus d’information, je vous renvoie à la documentation de GCC sur ces splendides designated initializers :

http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Designated-Inits.html

PS : Je n’ai pas encore réussi à déterminer si les champs non désignés étaient forcément égaux à 0, mais je vais tâcher de me renseigner 🙂

Publicités

2 Réponses

  1. Pingback: Initialisation des tableaux et des structures en C « Pierre Gradot

  2. Pingback: struct : déclarer des types et des variables en C | Pierre Gradot

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s