web-dev-qa-db-fra.com

Initialisation de l'union en C ++ et C

J'ai construit une bibliothèque C fonctionnelle, qui utilise des constantes, dans des 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 le .raw l'initialiseur est la syntaxe C uniquement.

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

30
Alex

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'une union peut être initialisé

J'ai trouvé cette explication sur: Initialisation des structures et des unions

15
hae

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

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 initialisés à zéro. (Avant C++ 11, il n'y avait aucun moyen d'initialiser des tableaux qui ne sont pas des objets complets.)

4
Kerrek SB

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

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

Déclarez plutôt la variable globale:

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

et l'initialiser dans une section globale:

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

et au lieu de bugger le compilateur C++ avec la syntaxe ANSI C99 moderne, je laisse l'éditeur de liens faire le travail en démêlant les symboles C.

2
Alex