typedef union

OP #6164155
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
Gast #6164196
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...
Gast #6164219
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?
Gast #6164268
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.
#6164277
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.
Gast #6164298
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;
}
Gast #6164323
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren