Initialisation de l'Union en C++ et C

J'ai construit une bibliothèque C de travail, qui utilise des constantes, dans les fichiers d'en-tête définis comme

typedef struct Y {
  union {
    struct bit_field bits;
    uint8_t raw[4];
  } X;
} CardInfo;

static const CardInfo Y_CONSTANT = { .raw = {0, 0, 0, 0 } };

Je sais que l'initialiseur .raw n'est que la syntaxe C.

Comment puis-je définir des constantes avec des unions d'une manière telle que je puisse les utiliser en C et c++.

26
demandé sur Mateusz Piotrowski 2012-07-19 11:16:09

4 réponses

J'ai eu le même problème. Pour C89, ce qui suit est vrai:

Avec les initialiseurs de style C89, les membres de structure doivent être initialisés dans l'ordre déclaré, et seul le premier membre d'un syndicat peut être initialisé

J'ai trouvé cette explication à: Initialisation des structures et des syndicats

15
répondu hae 2016-01-14 12:36:00

Je crois que C++11 vous permet d'écrire votre propre constructeur comme suit:

union Foo
{
    X x;
    uint8_t raw[sizeof(X)];

    Foo() : raw{} { }
};

Cette valeur par défaut-initialise une union de type Foo avec le membre actif raw, qui a tous les éléments zéro-initialisés. (Avant C++11, Il n'y avait aucun moyen d'initialiser des tableaux qui ne sont pas des objets complets.)

3
répondu Kerrek SB 2012-07-19 07:31:17

J'ai décidé de choisir le chemin suivant.

  • n'utilisez pas l'initialisation .member.
  • ne pas utiliser static const struct Foobar initialisation des membres

Déclarez plutôt la variable globale:

extern "C" {
  extern const struct Foobar foobar;
}

Et initialisez - le dans une section globale:

struct Foobar foobar = { 0, 0, 0, 0 };

Et au lieu de mettre sur écoute le compilateur C++ avec la syntaxe ANSI C99 moderne, je laisse l'éditeur de liens faire le travail en démangeant les symboles C.

2
répondu Alex 2012-07-27 01:48:17

C89 a permis l'initialisation des unions en listant directement l'élément que vous voulez initialiser (comme ce que vous avez dans votre code). C99 a changé cela pour que vous puissiez initialiser une union par son premier élément.

C++ n'autorise que cette forme d'initialisation - par le premier élément. C'est donc le code qui devrait fonctionner correctement dans les deux cas:

static const CardInfo Y_CONSTANT = {{0, 0, 0, 0 } };
1
répondu YePhIcK 2012-07-19 07:34:31