Forum: PC-Programmierung Frage zu Union in C++


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Erik R. (Gast)


Lesenswert?

Hallo,

ich habe folgenden C++-Code gefunden:
1
static constexpr const unsigned W = 64, H = 32;
2
3
struct Chip8
4
{
5
  union
6
  {
7
    // The Chip-8 has 0x1000 bytes of RAM.
8
    unsigned char Mem[0x1000] {0x12,0x00};
9
10
    struct
11
    {
12
      unsigned char V[16], DelayTimer, SoundTimer, SP, Keys[16], WaitingKey;
13
      unsigned char DispMem[W*H/8], Font[16*5]; // monochrome bitmaps
14
      unsigned short PC, Stack[12], I;
15
    };
16
  };
17
18
  // ...

Ist es in C++ in Ordnung, wenn ich z.B. in Stack oder PC schreibe und 
dann aus Mem lese (oder umgekehrt)? Oder wäre das "verbotenes" Type 
Punning?

von Nop (Gast)


Lesenswert?

Erik R. schrieb:

> Ist es in C++ in Ordnung, wenn ich z.B. in Stack oder PC schreibe und
> dann aus Mem lese (oder umgekehrt)? Oder wäre das "verbotenes" Type
> Punning?

Ja, letzteres. Union type punning ist in C erlaubt (seit C99 IIRC), aber 
in C++ ist es undefined behaviour. Es kann je nach Compiler aber 
trotzdem funktionieren, zumindest bis zu dem Compiler-Update, wo es das 
dann nicht mehr tut.

von Erik R. (Gast)


Lesenswert?

Danke für die Info. Generell ist in C++ die Verwendung von Unions dann 
wohl nicht besonders sinnvoll. Nur zum Sparen von Speicherplatz in 
manchen Situationen ... na ja.

von A. S. (achs)


Lesenswert?

Erik R. schrieb:
> Generell ist in C++ die Verwendung von Unions dann wohl nicht besonders
> sinnvoll. Nur zum Sparen von Speicherplatz in manchen Situationen ... na
> ja.

Eine wichtige Aufgabe ist es z.b., Nachrichten typisieren zu können.

von Achim M. (minifloat)


Lesenswert?

Nop schrieb:
> zumindest bis zu dem Compiler-Update, wo es das dann nicht mehr tut.

Da schreibste ein 'extern "C"' drumherum und dann sollte es doch ok 
sein. Hier geht es ja um Makroassembler-Registergefummel.

mfg mf

von Nop (Gast)


Lesenswert?

Achim M. schrieb:
> Hier geht es ja um Makroassembler-Registergefummel.

Dazu nutze ich das nicht (und schon gar nicht Bitfields), sondern für 
Datenstrukturen, bei denen ich eine Union nullen, kopieren oder auf 
Gleichheit prüfen will.

Manchmal auch nur komponentenweise auf Gleichheit, dann mit xor/and. Das 
ist auf einem Controller mit 32 bit elegant und schnell als Union über 
einen uint32_t, weil man damit nur einen Branch verursacht.

von Wilhelm M. (wimalopaan)


Lesenswert?

In C++ nutzt man dafür eine "typsichere Union", aka std::variant.

von cppbert3 (Gast)


Lesenswert?

Wilhelm M. schrieb:
> In C++ nutzt man dafür eine "typsichere Union", aka std::variant.

damit bekommt er aber nicht das Union-Verhalten - er moechte ja ueber ja 
ueber Mem oder gezielt zugreifen

von Wilhelm M. (wimalopaan)


Lesenswert?

cppbert3 schrieb:
> damit bekommt er aber nicht das Union-Verhalten - er moechte ja ueber ja
> ueber Mem oder gezielt zugreifen

Oh ja, ich hatte das nur überflogen ... ich las irgendwo: Speicherplatz 
... sorry.

Nun, dann braucht er std::bit_cast<>()

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Da Mem ein Char Array ist, würde es auch ein reinterpret_cast tun. Und 
gcc erlaubt als Spracherweiterung auch das Type-pruning.

Oliver

von MaWin (Gast)


Lesenswert?

cppbert3 schrieb:
> das Union-Verhalten - er moechte ja ueber ja
> ueber Mem oder gezielt zugreifen

Ist das der Sinn und Zweck von 'union'? Wäre es C Standard?

Beitrag #6610498 wurde vom Autor gelöscht.
von Kaj (Gast)


Lesenswert?

MaWin schrieb:
> Wäre es C Standard?

Nop schrieb:
> Union type punning ist in C erlaubt (seit C99 IIRC)

von Rolf M. (rmagnus)


Lesenswert?

MaWin schrieb:
> cppbert3 schrieb:
>> das Union-Verhalten - er moechte ja ueber ja
>> ueber Mem oder gezielt zugreifen
>
> Ist das der Sinn und Zweck von 'union'?

Nein.

> Wäre es C Standard?

Es wurde nachträglich in C erlaubt, weil es so häufig dafür genutzt 
wurde.

von mh (Gast)


Lesenswert?

Achim M. schrieb:
> Nop schrieb:
>> zumindest bis zu dem Compiler-Update, wo es das dann nicht mehr tut.
>
> Da schreibste ein 'extern "C"' drumherum und dann sollte es doch ok
> sein. Hier geht es ja um Makroassembler-Registergefummel.
>
> mfg mf

Nö, hier hilft extern "C" nicht, das macht etwas ganz anderes.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.