Hallo,
ich bin gerade auf der Suche nach einer Möglichkeit 16 Schalter bitweise
zu setzen
hab die Schalter wie folgt angelegt
union
{
int byte;
struct
{
unsigned Leds1:1;
unsigned Leds2:1;
unsigned Leds3:1;
unsigned Leds4:1;
unsigned Leds5:1;
unsigned Leds6:1;
unsigned Leds7:1;
unsigned Leds8:1;
unsigned Leds9:1;
unsigned Leds10:1;
unsigned Leds11:1;
unsigned Leds12:1;
unsigned Leds13:1;
unsigned Leds14:1;
};
}volatile ledset;
wenn ich jetzt mit
ledset |=(1<<1);
darauf zugreife bekomme ich vom Compiler eine Fehlermeldung
../main.c:19: error: invalid operands to binary | (have 'union
<anonymous>' and 'int')
Wenn jetzt jemand sagt "ist doch klar sind ja 2 Bytes "
hat er recht nur bin ich mit meiner Anwendung noch nicht weiter
Kann mir jemand eine andere Möglichkeit nennen da ich die Schalter in
einer Schleife sowohl abfragen als auch setzen oder löschen möchte
im Voraus besten dank
Wolfgang
Entschuldige, aber was genau sagt diese Fehlermeldung?
>../main.c:19: error: invalid operands to binary | (have 'union <anonymous>' >and
'int')
Ich übersetze sie mal ins Deutsche, falls das das Problem ist:
../main.c:19: Fehler: ungültige Operanden für binar | (hat 'union
<anonym>' und 'int')
Das Problem ist erstmal nicht ob ein oder zwei Bytes. Das Problem ist,
das der Compiler nicht weiss, welches der union Mitglieder er nun
behandeln soll. Das eine, das Du mit "byte" benannt hast, ist es wohl
nicht. Aber, nur mal angenommen, Du wolltest (<ironie> das ist natürlich
völlig abwegig </ironie>) die struct irgendwie am Schlafittchen packen,
sie wollte von Dir, das Du ihren Namen nennst, sonst will Sie Dein Kind,
wie würdest Du sie wohl nennen?
Hallo,
was du da sagst gib ich dir recht, habe ich aber auch schon geschrieben
ändert aber nichts an der Tatsache,das es so "nicht" geht.
wenn ich die union jetz aber in 2 Bytwerte unterteile kann ich sie ja
nicht mehr als ein ganzes in einer Schleife ansprechen.
By
Wolfgang
>was du da sagst gib ich dir recht, habe ich aber auch schon geschrieben
So? Wo ist der Code?
>ändert aber nichts an der Tatsache,das es so "nicht" geht.
Worin äussert sich das?
>wenn ich die union jetz aber in 2 Bytwerte unterteile kann ich sie ja>nicht mehr als ein ganzes in einer Schleife ansprechen.
Ich zitiere mich mal selbst:
>Das Problem ist erstmal nicht ob ein oder zwei Bytes. Das Problem ist,>das der Compiler nicht weiss, welches der union Mitglieder er nun>behandeln soll. Das eine, das Du mit "byte" benannt hast, ist es wohl>nicht. Aber, nur mal angenommen, Du wolltest (<ironie> das ist natürlich>völlig abwegig </ironie>) die struct irgendwie am Schlafittchen packen,>sie wollte von Dir, das Du ihren Namen nennst, sonst will Sie Dein Kind,>wie würdest Du sie wohl nennen?
>wenn ich die union jetz aber in 2 Bytwerte unterteile kann ich sie ja>nicht mehr als ein ganzes in einer Schleife ansprechen.
Du willst hier mehrere Probleme auf einmal lösen, denke ich. Das ist
ganz sinnlos.
1. Überleg Dir was Du erreichen willst.
2. Überleg Dir wie Du es erreichen willst.
Der Witz bei der union ist ja gerade das ich hier mehrere Typen haben
kann die sich im Speicher überdecken.
union {
struct bytewise {
byte a;
byte b;
} ab;
int c;
float d;
double k;
};
Mit Schleife oder Krawatte hat das nichts zu tun.
Nur, Du musst die Dinger irgendwie benennen. Oben hat ist Dein
union-Mitglied nicht benannt. Nur ein anynymes Ding.
>Bringt wohl so nichts
Ja. So fertige Tütenlösungen für Copy'nPaste sind nicht meine Sache. Ich
helfe unter der Voraussetzung das der Beratene liest und mitdenkt.
union
{
int byte;
struct
{
unsigned Leds1:1;
unsigned Leds2:1;
unsigned Leds3:1;
unsigned Leds4:1;
unsigned Leds5:1;
unsigned Leds6:1;
unsigned Leds7:1;
unsigned Leds8:1;
unsigned Leds9:1;
unsigned Leds10:1;
unsigned Leds11:1;
unsigned Leds12:1;
unsigned Leds13:1;
unsigned Leds14:1;
};
}volatile ledset;
wenn ich jetzt mit
ledset |=(1<<1);
was mich da wundert
meckert der compiler nicht ?
wegen unsigned Ledsxxx? da fehlt iwie ein datentyp
dann würde es glaube gehen wenn man den member der union anspricht
also ledset.byte |= (1<<1);
oder ledset.lLeds1
Urks schrieb:
>>Bringt wohl so nichts>> Ja. So fertige Tütenlösungen für Copy'nPaste sind nicht meine Sache. Ich> helfe unter der Voraussetzung das der Beratene liest und mitdenkt.
verlangt ja auch keiner von dir .
ich bin ja froh über jede Antwort.
Es ist ja nicht so das ich hier gleich meine Frage stelle ohne mich
vorher anderweitig zu informieren.
Eine Antwort zeigt einen schließlich wenn mann in die falsche Richtung
denkt.
C ist halt nicht Assembler und schon gar nicht Delphi.
Aufgrund vorheriger Antworten stellt sich mir schon wieder eine neue
Frage.
Was bedeutet dieses:
union {
struct bytewise {
byte a;
byte b;
} ab;
int c;
float d;
double k;
};
wie spreche ich jetzt byte a an ?
By
Wolfgang
Johann L. schrieb:
> Schreib das "byte" (das ein Word ist) hinter die anonyme Struktur!
???
Das "byte" ist doch hier anscheinend ein eigener 8-Bit Typ.
Schon klar, dass er vergessen hat, hier überhaupt eine konkrete Variable
zu definieren. Daher das "XXX" in meinem Post.
Stefan Ernst schrieb:
> Johann L. schrieb:>> Schreib das "byte" (das ein Word ist) hinter die anonyme Struktur!>> ???>> Das "byte" ist doch hier anscheinend ein eigener 8-Bit Typ.
Stefan Ernst schrieb:
> Ach so, das war auf die ursprüngliche Frage bezogen, nicht auf die neue> (wie meins). ;-)
Jepp. Zu Beachten auf AVR ist allerdings Compilerfehler: avr-gcc
Woher kommt eigentlich dieser Unsinn, erst mal grundsätzlich mit
anonymen Strukturen und Unions um sich zu schmeissen?
Jeder meint immer, er muss so seinen Quellcode so kompakt wie nur
irgendwie möglich schreiben um dann irgendwann festzustellen, dass man
sich damit eigentlich meistens ins eigene Knie schiesst.
Gebt doch den eigenen Datentypen Namen!
(Und kauft euch ein C-Buch um zu lernen was denn der ganze
Buchstabenhaufen eigentlich bedeutet)
> Der Witz bei der union ist ja gerade das ich hier mehrere Typen haben> kann die sich im Speicher überdecken.
Daß sie sich im Speicher überdecken, ist eher ein Nebeneffekt. Eine
union ist im Prinzip eine struct, bei der ich nicht mehrere Member
gleichzeitig benutzen darf. In C ist es eigentlich verboten, aus einer
union ein anderes Element zu lesen, als das, das man zuletzt beschrieben
hat. Eine Konvertierung über den Umweg einer Union ist nicht vorgesehen
und eigentlich ein Fehler. Dafür sind Casts gedacht.
Rolf Magnus schrieb:
>> Der Witz bei der union ist ja gerade das ich hier mehrere Typen haben>> kann die sich im Speicher überdecken.>> Daß sie sich im Speicher überdecken, ist eher ein Nebeneffekt. Eine> union ist im Prinzip eine struct, bei der ich nicht mehrere Member> gleichzeitig benutzen darf. In C ist es eigentlich verboten, aus einer> union ein anderes Element zu lesen, als das, das man zuletzt beschrieben> hat. Eine Konvertierung über den Umweg einer Union ist nicht vorgesehen> und eigentlich ein Fehler. Dafür sind Casts gedacht.
Ein Cast ist eine Typumwandlung, eine Union ist eine andere Sicht auf
die Daten. Das ist was komplett anderes.
Es ist zB nicht möglich, eine Struktur auf eine andere zu Casten. Ebenso
liefert ein
1
floatf;
2
inti=(int)float;
was komplett anderes ab als eine Union einmal als .asInt und einmal als
.asFloat auszulesen, womit man auf die Binärdarstellun eines float
zugreifen kann und wie es bei Soft-Float Implementierungen auch gemacht
wird und korrekt ist. Der Cast beinhaltet hingegen nen ganzen Batzen
Arithmetik.
Johann
> Ein Cast ist eine Typumwandlung, eine Union ist eine andere Sicht auf> die Daten. Das ist was komplett anderes.
Dafür ist eine Union gar nicht gedacht. Eine andere Sicht bekommst du,
indem du die Adresse einer Variablen nimmst und dann in einen Pointer
auf den gewünschten Zieltyp castest.
> Es ist zB nicht möglich, eine Struktur auf eine andere zu Casten.
Es ist aber möglich, einen Zeiger darauf zu Casten und dann zu
dereferenzieren.
Rolf Magnus schrieb:
>> Ein Cast ist eine Typumwandlung, eine Union ist eine andere Sicht auf>> die Daten. Das ist was komplett anderes.>> Dafür ist eine Union gar nicht gedacht. Eine andere Sicht bekommst du,> indem du die Adresse einer Variablen nimmst und dann in einen Pointer> auf den gewünschten Zieltyp castest.>>> Es ist zB nicht möglich, eine Struktur auf eine andere zu Casten.>> Es ist aber möglich, einen Zeiger darauf zu Casten und dann zu> dereferenzieren.
Das birgt Fehler durch Strikt-Aliasing.
Von Dinge, die je nachdem, wie weit ein C-Compiler gegen die
C-Spezifikation optimiert, abschmieren oder nicht, sollte man die Finger
lassen.
Früher oder später wird dann wieder rumgeheult "Compilerfehler: GCC
macht falschen Code bei Optimierung".
Johann
Und bevor Fragen kommen, darf ich aus dem GCC-Handbuch zitieren:
-fstrict-aliasing
Allows the compiler to assume the strictest aliasing rules applicable to
the language being compiled. For C (and C++), this activates
optimizations based on the type of expressions. In particular, an object
of one type is assumed never to reside at the same address as an object
of a different type, unless the types are almost the same. For example,
an unsigned int can alias an int, but not a void* or a double. A
character type may alias any other type.
Pay special attention to code like this:
1
uniona_union{
2
inti;
3
doubled;
4
};
5
6
intf(){
7
a_uniont;
8
t.d=3.0;
9
returnt.i;
10
}
The practice of reading from a different union member than the one most
recently written to (called “type-punning”) is common. Even with
-fstrict-aliasing, type-punning is allowed, provided the memory is
accessed through the union type. So, the code above will work as
expected. See Structures unions enumerations and bit-fields
implementation. However, this code might not:
1
intf(){
2
a_uniont;
3
int*ip;
4
t.d=3.0;
5
ip=&t.i;
6
return*ip;
7
}
Similarly, access by taking the address, casting the resulting pointer
and dereferencing the result has undefined behavior, even if the cast
uses a union type, e.g.:
1
intf(){
2
doubled=3.0;
3
return((uniona_union*)&d)->i;
4
}
The -fstrict-aliasing option is enabled at levels -O2, -O3, -Os.
Johann