Forum: Compiler & IDEs Union Problem: Array mit einigen Variablen "überlagern"


von Michl, Ombreee (Gast)


Lesenswert?

Hi zusammen,

vorab, ich bin mir dessen bewusst, dass die suche noch funktioniert, hab 
sie ja gerad Stunden lang gequält. Gefunden hab ich auch alles Mögliche, 
nur nichts was mich weiterbringt. Daher: Entschuldigung für noch eine 
"Union"-Thema.

Zu meinem Problem:
ich möchte auf 10 aneinander gereihte Bytes sowohl per Index zugreifen 
(also ein Array) als auch über eine Mischung aus uint16_t und uint8_t.
Etwas verständlicher:
die 10 Bytes
  uint16_t var1,
  uint16_t var2,
  uint8_t var3,
  uint8_t var4,
  uint8_t var5,
  uint8_t var6,
  uint8_t var7,
  uint8_t var8
sollen in obiger Reihenfolge über das Array
  uint8_t arr[10]
gelesen und geschrieben werden können.

Allgemein sollte dafür mMn eine union die richtige Wahl sein. Nur 
irgendwie stell ich mich wohl an.
1
union union_t
2
{
3
    struct
4
    {
5
      uint16_t var1,
6
      uint16_t var2,
7
      uint8_t var3,
8
      uint8_t var4,
9
      uint8_t var5,
10
      uint8_t var6,
11
      uint8_t var7,
12
      uint8_t var8
13
    };
14
    uint8_t array[10];
15
};
16
17
...
18
int main( void ){
19
   union_t beides;
20
   ...
21
}

Jetzt steh ich irgendwie grad aufm Schlauch. Wie sprech ich die jetz an?
beides.array[x] ist das x-te byte?
beides.var2 entspricht ( (beides.array[2]<<8) | beides.array[3] ) , 
oder?
Es scheint mir nur, das funktioniert nicht?!

Wenn ich beides.var2 = 3 setze und daraufhin beides.array[2] lese hat 
dies irgendwie einen zufälligen Wert habe ich das Gefühl.

Kann mir jemand bestätigen, dass der "Code" oben so fehlerfrei ist?
Dann such ich nämlich den Fehler an anderer stelle weiter.

Vielen Dank
Michael

von Michl, Ombreee (Gast)


Lesenswert?

PS: Man sollte speichern, dann kommen auch vom Compiler Warnungen und 
Errors beim compilieren.
Aber was will mir da jetzt

../main.c:23: error: 'union_t' undeclared (first use in this function)

sagen?

von Helfer (Gast)


Lesenswert?

Dir fehlt ein typedef und die Syntax dafür.

Du willst einen eigenen Namen union_t für die Datenstruktur union {...} 
definieren und wie du das machst ist es falsch.

von DirkB (Gast)


Lesenswert?

schreib doch ein union davor ( und ein = {0}) dahinter.
1
int main( void ){
2
   union union_t beides = {0};
3
   ...
4
}


Und das mit (beides.array[2]<<8) | beides.array[3] )hängt von der 
Endianess deines Systems ab.

Und dann sind da noch ein paar Kommas zuviel ( und ; zu wenig)

Woher weißt du das da zufällige Werte drin stehen? Wie gibst du das aus?

von Nachtaktiver (Gast)


Lesenswert?

Mein C-Buch sagt mir das die einzelnen Variablen in der Struktur nicht 
mit einen Komma, sondern mit einen Punkt-Komma abgeschlossen werden
1
struct {
2
unsigned char BLA;
3
unsigned char BLUB;
4
}

Ansonsten bin ich mir gar nicht sicher ob das überhaupt geläufig ist. 
Ich habe schon Strukturen gesehen in denen es Unions gibt, aber eine 
Union mit einer Struktur habe ich bisher nocht nicht gesehen.

von Michl, Ombreee (Gast)


Lesenswert?

DirkB schrieb:
> Und dann sind da noch ein paar Kommas zuviel ( und ; zu wenig)

Hat mein Compiler auch bemängelt und ich habs still und heimlich 
verbessert... sorry

> Woher weißt du das da zufällige Werte drin stehen? Wie gibst du das aus?

AVR-Studio mit Simulator, der sich soeben verabschiedet hat. Error und 
AVR-Studio ist weg... grr



Nachtaktiver schrieb:
> Ansonsten bin ich mir gar nicht sicher ob das überhaupt geläufig ist.
> Ich habe schon Strukturen gesehen in denen es Unions gibt, aber eine
> Union mit einer Struktur habe ich bisher nocht nicht gesehen.

Naja ich bin blutiger Anfänger... Aber wie geht man das sonst an?
"Problem":
Ich möchte mit meinem AVR ein Datenpacket per UART empfangen und 
anschließend auswerten. An der UART-Schnittstelle kommt ein Byte nach 
dem Anderen rein, im Programm kann ich aber viel besser einzelne 
Variablen brauchen?!



Ich frage mich gerde ob ich für korrekte Funktion dem strukt einen namen 
geben muss?! also so:
1
typedef union {
2
    struct {
3
      uint16_t var1;
4
      uint16_t var2;
5
      uint8_t var3;
6
      uint8_t var4;
7
      uint8_t var5;
8
      uint8_t var6;
9
      uint8_t var7;
10
      uint8_t var8;
11
    } name;
12
    uint8_t array[10];
13
} union_t ;
Oder müsste das auch ohne gehen? wär mir lieber!

von Helfer (Gast)


Lesenswert?

> Oder müsste das auch ohne gehen? wär mir lieber!

IMHO nur mit

von Stefan E. (sternst)


Lesenswert?

Helfer schrieb:
>> Oder müsste das auch ohne gehen? wär mir lieber!
>
> IMHO nur *mit*

GCC erlaubt auch anonyme Strukturen.

von DirkB (Gast)


Lesenswert?

Ohne Namen geht es auch.

Caste doch die Struktur auf ein *uint8_t;

Also
1
int DatenLesen(uint8_t *Daten);
2
3
...
4
5
DatenLesen((uint8_t *)&name);

von Michl, Ombreee (Gast)


Lesenswert?

Danke euch allen! Dieser Teil scheint zu funktionieren, mein Gesamtcode 
allerdings nicht.
Ich mach mich mal auf die suche nach dem richtigen Konzept, meins geht 
nicht auf...

DirkB schrieb:
> Caste doch die Struktur auf ein *uint8_t;
>
> Also
> int DatenLesen(uint8_t *Daten);
> ...
> DatenLesen((uint8_t *)&name);

Tut mir leid, dem kann ich nicht folgen. Auch nach einigem googeln 
nicht.
Wäre schön wenn du das nochmal genauer erläutern könntest.

Danke
Lg Michael

von Rolle (Gast)


Lesenswert?

Syntax steht in jedem Buch,
aber was gerne vergessen wird:

Du must dem Compiler unbedingt sagen dass er Deine
Struktur "packen" soll !
(z.B. bei gcc -fpack-struct )

einige Compiler haben da ihre Eigenheiten beim alignment wenn 
unterschiedliche Datentypen in der Struktur drin sind

das big-endian/little-endian Problem wurde schon angesprochen

ansonsten viel Spass noch

von Andreas B. (Gast)


Lesenswert?

Rolle schrieb:
> Du must dem Compiler unbedingt sagen dass er Deine
> Struktur "packen" soll !
> (z.B. bei gcc -fpack-struct )

Dann packt der aber alle Strukturen, was ziemlich suboptimal ist. Mit 
dem Attribut "packed" kann man das auch für einzelne structs einstellen.

Rolle schrieb:
> einige Compiler haben da ihre Eigenheiten beim alignment wenn
> unterschiedliche Datentypen in der Struktur drin sind

Normalerweise sind es weniger die eigenbrötlerischen Compiler sondern 
mehr die ABI-Standards der Prozessor-Architekturen die sie einhalten 
müssen um auch zu anderen Compilern kompatibel zu sein.

von Michl, Ombreee (Gast)


Lesenswert?

http://books.google.com/books?id=8XqqSxeih7UC&pg=PA193&lpg=PA193&dq=c%2B%2B+strukturen+packen&source=bl&ots=W-ba7nW-sZ&sig=ZMETjlch3HFLB6OGzF72jywmKlY&hl=de&ei=ImaPTeHWGo-Lswbe__mFCg&sa=X&oi=book_result&ct=result&resnum=2&ved=0CBwQ6AEwAQ#v=onepage&q=c%2B%2B%20strukturen%20packen&f=false

Also alles was ich über gepackte Stukturen so lese is im Prinzip das was 
in obigem Link steht (hoffentlich funktioniert er! ist aus dem Buch 
"Praktische C++-Programmierung" von Steve Oualline auf den Seiten 192 f 
)
Und da steht, dass durch das Packen die Bits quasi auf unterschiedliche 
Variablen verteilt werden können um Speicher zu sparen.
Aber was hat das mit meiner struct zu tun? warum soll ich die Packen?

von Helfer (Gast)


Lesenswert?

Damit der C-Compiler nicht Lücken in die Struktur macht, um die Hände 
frei zu haben um z.B. effizienteren Zugriffscode zu erzeugen.

von Andreas B. (Gast)


Lesenswert?

Ein C-Compiler darf zwischen die Elemente eines struct Füll-Bytes 
einfügen, um die Ausrichtung folgender Elemente zu steuern. Das struct 
aus der Frage könnte so mehr als 10 Bytes groß sein, je nach Architektur 
für die übersetzt wird. Das "packed"-Attribut des GCC verhindert das, 
jedes Element folgt dann direkt dem vorhergehenden.

von Glaskugel (Gast)


Lesenswert?

>Also alles was ich über gepackte Stukturen so lese is im Prinzip das was
in obigem Link steht

>Und da steht, dass durch das Packen die Bits quasi auf unterschiedliche
Variablen verteilt werden können um Speicher zu sparen.

Situation:

1. Oben angegebener Link beschreibt einen Spezialfall, bei dem eine 
Variable deutlich weniger Information halten soll, als mit den 
Standardtypen gespeichert werden kann.

Schlussfolgerung:
1. Die Situation ist mit der des TO nicht unmittelbar vergleichbar.

Information:
1. Der Fall des TO passt auf das packen von Bytes/Words etc. also 
mehreren Bits zusammen.

Empfehlung:
1. Mehr als ein Buch zu dem Thema "structs packen" heranziehen.

von Michl, Ombreee (Gast)


Lesenswert?

http://sig9.com/articles/gcc-packed-structures
Dieser Fall ist wohl gemeint... Ok das ist natürlich ein Argument!
Danke!

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.