Forum: Mikrocontroller und Digitale Elektronik typedef union


von Bernd S. (soundgott)


Lesenswert?

Ich habe folgendes Problemchen:
gegeben ist eine Datenstruktur z.B.:

union Data_u
{
  int elementA;
  int elementB;
  ..
  float elementC;
};

das ganze in  eine typedef verpackt:


typedef union
{
  int elementA;
  int elementB;
  ..
  float elementC;
}TypData_u;

soweit zu Vorgeschichte. Nun will ich das ganze in einer Klasse 
anwenden:

Header:
class foo
{
public:
  foo();

  Data_u      memberA;
  TypData_u   memberB;
  int         nochwas[10]; // nur als beispiel
};

Implementierung:

foo::foo()
{
   memset( &memberA, 0, sizeof(memberA)); // zeile A
   memset( &memberB, 0, sizeof(memberB)); // Zeile B
}

Eigentlich sollten beide Zeilen den gleichen Effekt haben -->
haben sie aber nicht, Zeile B funktioniert einwandfrei, nach der 
Ausführung
von Zeile A werden Teile der in der Klasse nach memberA vorhandenen 
Daten mit murks überschrieben (z.B. nochwas[] ).

Compiler: MS Visual Studio 2017 (Version 19.16.27034.0)

Hat jemand der verehrten Softis eine Erlärung dafür.
Danke vorab

von Mork (Gast)


Lesenswert?

Bernd S. schrieb:
> foo::foo()
> {
>    memset( &memberA, 0, sizeof(memberA)); // zeile A
>    memset( &memberB, 0, sizeof(memberB)); // Zeile B
> }

Erklär doch mal, was Du glaubst, an dieser Stelle zu tun. Vielleicht 
kommst Du dann von selbst drauf ;)

von Bernd S. (soundgott)


Lesenswert?

0 setzen, was sonst?
 momentan könnte ich den Unterschied nicht erklären
(oder ich habe das berühmte Brett vorm Kopf)

von Musikant (Gast)


Lesenswert?

1
typedef union
2
{
3
  int elementA;
4
  int elementB;
5
  ..
6
  float elementC;
7
}TypData_u;

...sollte vermutlich eher ein struct werden, kein union, oder?
1
typedef struct
2
{
3
  int elementA;
4
  int elementB;
5
  ..
6
  float elementC;
7
}TypData_u;

sollte funktionieren...

von Bernd S. (soundgott)


Lesenswert?

Nee, nee, ich meinte schon typedef union

von Nick M. (Gast)


Lesenswert?

Bernd S. schrieb:
> Data_u      memberA;

Jetzt?

von Programmierer (Gast)


Lesenswert?

Ich glaube typedef macht nicht das was du glaubst was es macht. Du hast 
letztlich "Data_u" und "TypData_u" als zwei separate unions definiert 
die aber den gleichen Inhalt haben... Ziemlich sinnlos.

Bernd S. schrieb:
> das ganze in  eine typedef verpackt:
>
> typedef union {
>   int elementA;
>   int elementB;
>   ..
>   float elementC;
> }TypData_u;

Was "das ganze"? Das ist ein komplett neues union, wenn auch mit 
gleichem Inhalt. Wozu ist das gut?

von Bernd S. (soundgott)


Lesenswert?

immer noch nicht.

denn es ergibt

sizeof(memberA) ist = sizeof(memberB)

trotzdem gibts inder Zeile
 memset( &memberA, 0, sizeof(memberA));

Müll

von Bernd S. (soundgott)


Lesenswert?

@Programmierer:

das die beiden Variablen den gleichen Inhalt haben ist mir schon klar,
dient ja nur als Beispiel. mir gehts um den "angeblichen" Unterschied
zwischen union und typedef union, den der Comiler offensichtlich in dem 
Beispiel macht.

von Bernd S. (soundgott)


Lesenswert?

Ergänzung:

In der tatsächlichen Quelle bestehen die einzelnen Elemente nicht aus 
ints, sondern aus verschiedenen strukturen. Tut im Endeffekt aber nicht 
zu Sache selber

von (prx) A. K. (prx)


Lesenswert?

Zwischen
  union X { ... };
und
  typedef union { ... } X;
und
  typedef union X { ... } X;
besteht in C++ kein Unterschied. In C schon.

von Theor (Gast)


Lesenswert?

Es ist an sich ein richtiger Gedanke, das Problem an einem 
vereinfachten, minimalem Code zu zeigen. Nur muss dieser Code auch 
fehlerfrei compilieren.

Falls ich nicht wieder was Neues bei C++ übersehen habe, ist der Name 
einer union kein Typ; und kann also nicht als Typangabge fungieren. 
Der Code ist also m.M.n. nicht compilierbar. Die Zeile:
1
Data_u      memberA;

sollte, wenn ich richtig liege, eine Fehlermeldung ergeben, die ungefähr 
lautet "... or type expected".

Bitte überprüfe das und poste (als Anhang oder CopyPaste) genau diesen 
Code, ohne aptipppen, ohne nachträgliches Redigieren.

von Bernd S. (soundgott)


Lesenswert?

@Theor

es wäre schön, wenn es Fehlermeldungen gäbe, leider ein Wunschdenken.
es kompilieren (und linken) beide Varianten, nur bei der "union" gibts 
dann
die Probleme.

von (prx) A. K. (prx)


Lesenswert?

Theor schrieb:
> Falls ich nicht wieder was Neues bei C++ übersehen habe,

Die Deklarationen
  union X;
  struct Y;
  class Z;
entsprechen dem gleichen syntaktischen Konstrukt und definierten in C++ 
bereits von Anfang an Typen.

In C ist das anders, da gehören die Namen hinter union und struct zu 
einem eigenen Namespace und sind keine Typen.

Sowas wie
  typedef union X { ... } X;
ist in C nicht weiter ungewöhnlich, weil es den Namen X in zwei 
verschiedenen Namespaces definiert. In C++ wäre das eigentlich eine 
doppelte Definition, weil zweimal im gleichen Namespace, wird aber als 
Konzession an C dennoch akzeptiert.

von Udo K. (Gast)


Lesenswert?

Ich habe dein Beispiel compiliert, und es tut wie es soll.
Sowohl mit gcc als auch mit cl.
Beide Variablen werden richtig auf 0 gesetzt.
Eventuell liegt der Fehler woanders?

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

union Data_u
{
    int elementA;
    int elementB;
    float elementC;
};

typedef union {
    int elementA;
    int elementB;
    float elementC;
} TypData_u;

class foo {
    public:
        foo();

        Data_u      memberA;
        TypData_u   memberB;
        int         nochwas[10];
};

foo::foo() {

    printf("Init\n");

    printf("%p %p %p\n", this, &memberA, &memberB);
    printf("%ld %ld %ld\n", sizeof(*this), sizeof(memberA), 
sizeof(memberB));

    memberA.elementA = 1;
    memberB.elementA = 2;

    nochwas[0] = 3;

    printf("%d %d %d\n", memberA.elementA, memberB.elementB, 
nochwas[0]);

    memset( &memberA, 0, sizeof(memberA)); // zeile A
    memset( &memberB, 0, sizeof(memberB)); // Zeile B

    printf("%d %d %d\n", memberA.elementA, memberB.elementB, 
nochwas[0]);
}

foo x;

int main()
{
    return 0;
}

von Theor (Gast)


Lesenswert?

Ja. Du hast wohl recht. Unions sind in CPP (fast) äquivalent zu Klassen 
und ihr Name kann als Typ verwendet werden. Sorry.

von as (Gast)


Lesenswert?

Bernd S. schrieb:
> Data_u      memberA;

Wieso compiliert das? Ohne union davor.

von (prx) A. K. (prx)


Lesenswert?

as schrieb:
> Bernd S. schrieb:
>> Data_u      memberA;
>
> Wieso compiliert das? Ohne union davor.

Bisschen was vom Thread gelesen?

von Ingoh (Gast)


Lesenswert?

Bernd S. schrieb:
> Eigentlich sollten beide Zeilen den gleichen Effekt haben -->
> haben sie aber nicht, Zeile B funktioniert einwandfrei, nach der
> Ausführung
> von Zeile A werden Teile der in der Klasse nach memberA vorhandenen
> Daten mit murks überschrieben (z.B. nochwas[] ).

Poste doch bitte mal den Code, mit dem Du das feststellst.


Außerdem:
Vorsicht bei der Verwendung von unions.
1
union Data_u
2
{
3
  int elementA;
4
  int elementB;
5
  float elementC;
6
};

...bedeutet nicht, dass Du einen neuen Datentyp geschaffen hast, der 
zwei int und ein float enthält.
Evtl. liegt es einfach nur an Deinem minimal-Beispiel, aber die 
Beispiel-UNIONs ergeben wenig Sinn.

von Ingoh (Gast)


Lesenswert?

Theor schrieb:
> Unions sind in CPP (fast) äquivalent zu Klassen

Definiere "(fast)" ;)

https://en.cppreference.com/w/cpp/language/union

von as (Gast)


Lesenswert?

A. K. schrieb:
> Bisschen was vom Thread gelesen?

Ja, sorry, war zu lange offen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Und was soll denn hier drin stehen Deiner Meinung nach?
1
  int         nochwas[10]; // nur als beispiel

Also, wie stellst DU fest, dass der Inhalt darin überschrieben wird?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.