Union-Initialisierung in C++ und C

Lesezeit: 2 Minuten

Benutzeravatar von Alexander Oh
Alexander Ach

Ich habe eine funktionierende C-Bibliothek erstellt, die Konstanten verwendet, in Header-Dateien, die als definiert sind

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

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

Ich weiß, dass die .raw initializer ist nur C-Syntax.

Wie definiere ich Konstanten mit Unions so, dass ich sie in C und C++ verwenden kann?

  • Sind Sie sicher, dass es sich um das Mixed-Mode-Tag handelt?

    – Sebastian Mach

    19. Juli 2012 um 7:17 Uhr

  • Initialisiert C++ nicht die unions durch das erste Element? Dh static const Y_CONSTANT = {{0,0,0,0}};

    – YePhIcK

    19. Juli 2012 um 7:19 Uhr


  • @YePhIcK dann gibt es zusätzliche Warnungen über fehlende Klammern.

    – Alexander Ach

    19. Juli 2012 um 7:22 Uhr

  • @Alex – Ich habe gerade meinen Code ausprobiert und er wurde ohne Fehler/Warnungen erstellt. Bist du sicher, dass du doppelte Klammern verwendest? typedef struct Y { union { struct bit_field bits; uint8_t roh[4]; } X; } Karteninfo; Statische Konstante CardInfo Y_CONSTANT = {{0, 0, 0, 0 } };

    – YePhIcK

    19. Juli 2012 um 7:31 Uhr


  • Das ist richtig und so ist die Sprache – Sie dürfen das ERSTE Element der Union initialisieren und nur das erste

    – YePhIcK

    19. Juli 2012 um 7:32 Uhr

haes Benutzeravatar

Ich hatte das gleiche Problem. Für C89 gilt:

Bei Initialisierern im C89-Stil müssen Strukturelemente in der deklarierten Reihenfolge initialisiert werden, und nur das erste Element einer Union kann initialisiert werden

Diese Erklärung habe ich gefunden unter:
Initialisierung von Strukturen und Vereinigungen

Ich glaube, dass C ++ 11 es Ihnen ermöglicht, Ihren eigenen Konstruktor so zu schreiben:

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

    Foo() : raw{} { }
};

Dies initialisiert standardmäßig eine Vereinigung des Typs Foo mit aktivem Mitglied raw, bei der alle Elemente mit Null initialisiert sind. (Vor C++11 gab es keine Möglichkeit, Arrays zu initialisieren, die keine vollständigen Objekte sind.)

  • @Alex: Nein, natürlich nicht. Aber mit Glück wird die Struktur sein Layout-kompatibel mit einer ähnlich deklarierten C-Struktur …

    – Kerrek SB

    19. Juli 2012 um 7:35 Uhr

  • Ah, ich verstehe, also möchten Sie vorschlagen, es zu verwenden #ifdef __cplusplus an den richtigen Stellen, um diese Header-Datei integrierbar zu machen. Ah, das könnte noch unschärfer werden.

    – Alexander Ach

    19. Juli 2012 um 7:39 Uhr

  • Warnung: Das Hinzufügen eines Konstruktors entfernt PODness, was oft wünschenswert ist, wenn man mit Unions für den Speicherzugriff herumspielt.

    – Firmmo

    19. Juni 2013 um 15:13 Uhr

  • @Offfirmo C++11 hat einen neuen Begriff eingeführt Standard-Layout-Klasse , diese dürfen Konstruktoren haben; und viele Fälle, die POD in C++03 erforderten, erfordern jetzt nur noch das Standard-Layout. (POD ist jetzt als Standard-Layout plus einige andere Garantien definiert).

    – MM

    30. November 2014 um 23:32 Uhr

Ich habe mich für folgenden Weg entschieden.

  • Verwende nicht .member Initialisierung.
  • nicht verwenden static const struct Foobar Initialisierung von Mitgliedern

Deklarieren Sie stattdessen die globale Variable:

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

und initialisieren Sie es in einem globalen Abschnitt:

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

und anstatt den C++-Compiler mit moderner ANSI-C99-Syntax zu verwanzen, lasse ich den Linker die Arbeit erledigen, indem er C-Symbole entwirrt.

1386650cookie-checkUnion-Initialisierung in C++ und C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy