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
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 ;)
0 setzen, was sonst? momentan könnte ich den Unterschied nicht erklären (oder ich habe das berühmte Brett vorm Kopf)
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...
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?
immer noch nicht. denn es ergibt sizeof(memberA) ist = sizeof(memberB) trotzdem gibts inder Zeile memset( &memberA, 0, sizeof(memberA)); Müll
@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.
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
Zwischen
union X { ... };
und
typedef union { ... } X;
und
typedef union X { ... } X;
besteht in C++ kein Unterschied. In C schon.
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.
@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.
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.
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;
}
Ja. Du hast wohl recht. Unions sind in CPP (fast) äquivalent zu Klassen und ihr Name kann als Typ verwendet werden. Sorry.
as schrieb: > Bernd S. schrieb: >> Data_u memberA; > > Wieso compiliert das? Ohne union davor. Bisschen was vom Thread gelesen?
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.
Theor schrieb: > Unions sind in CPP (fast) äquivalent zu Klassen Definiere "(fast)" ;) https://en.cppreference.com/w/cpp/language/union
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.