Hallo,
ich bin langsam am verzweifeln...
Ich will einfach nur prüfen, ob zwei char-Werte gleich sind. Doch das
will einfach nicht funktionieren!
1
volatilecharpuffer[37];
2
3
voidByteEmfpangen(charempfangen)
4
{
5
[...]
6
7
chartmp
8
tmp=puffer[35];
9
uart_write_char(tmp);
10
if(tmp==0xFF)
11
{
12
MachWas();
13
}
14
15
[...]
16
}
Das will einfach nicht funktionieren! Auf der UART schickt mir der
Atmega32 ein 0xFF!? Also müsste die Bedingung doch erfüllt sein, aber er
führt einfach den Code in der Bedingung nicht aus (er müsste dann
nämlich eine LED anschalten, was er aber nicht tut).
Alle Fehler am Code (auser den mit der if-Bedingung), wie z.B. das die
UART nicht richtig sendet oder das die LED nicht funktioniert/falsch
angeschlossen ist, kann ich ausschließen. Hab das alles schon genügend
oft ausprobiert.
Ich weiß leider keinen Rat mehr. Hoffe, ihr könnt mir weiter helfen!
MfG
Julian
Klaus Wachtler schrieb:
> Vielleicht den Vergleich mal ändern zu: tmp == (char)0xFF
Das wars... Jetzt funzt es endlich! Puhh
Scheinbar stößt sich GCC daran, wenn da nicht extra (char) steht.
Kann diesen Sachverhalt mal jemand erklären?! Wieso interpretiert der
Compiler nicht von alleine 0xFF als char? Zumal ja tmp auch ein char
ist. Sollte es da Komplikationen geben, so müsste doch zumindest der
Compiler meckern, dass dort Äpfel mit Birnen verglichen wird.
Hannes schrieb:
> Schmarrn. 0xFF ist schon char.
Schmarrn. 0xFF ist immer vom Typ int. Alle Zahlen ohne Suffix die in
int passen sind int. Und wenn char vorzeichenbehaftet ist (also oft),
dann passt es auch nicht mal rein.
>Das soll bedeuten, das da noch weitere Code steht, der jetzt aber nicht>für mein Problem relevant ist. Da wird dieser Parameter noch benötigt.
Wenn du schon genau weißt, wo der Fehler steckt, warum fragst du dann
überhaupt noch?
>Alle Fehler am Code (auser den mit der if-Bedingung), wie z.B. das die>UART nicht richtig sendet oder das die LED nicht funktioniert/falsch>angeschlossen ist, kann ich ausschließen.
Na prima. Das ist mal wieder einer der Fälle, in denen ein garantiert
fehlerfreies Programm nicht funktioniert - denn die paar Zeilen
gezeigter Code sind ebenfalls richtig. Da bleibt, wie in 99% der auch
sonst hier vorkommenden Fälle, als Ursache nur noch ein Compilerfehler
oder ein bisher unerkannter Bug im Prozessor.
Geh einfach mal davon aus, das der Compiler sowas wie
Was lernen wir daraus?
Wenn von echten Texten die Rede ist, kann man char benutzen (solange man
sich im Bereich ASCII Code bewegt).
Wenn man aber von Bytes redet, ist char einfach der falsche Datentyp.
Für Bytes benutzt man immer unsigned char.
Dann passieren solche Probleme nicht.
Oliver schrieb:
> Geh einfach mal davon aus, das der Compiler sowas wie>
1
if(tmp==0xFF)
2
>{
3
>
> absolut fehlerfrei übersetzt.
LOL.
Klar macht er das. Die Frage ist eher: Weiß der Fragesteller, was hier
richtig ist :-)
Richtig ist:
Wir wissen, das char beim avr-gcc ein signed char ist und das avr-gcc
2-er Komplementarithmetik benutzt.
tmp ist ein char und enthält 0xFF
die Konstante 0xFF ist wie alle Konstanten erst mal ein int (dezimal
255). Damit stehen im Vergleich sich die beiden Datentypen
if( char == int )
gegenüber.
Die C-Regeln verlangen, dass der kleinere der beiden Typen auf den
Datentyp des größeren gehievt wird. In dem Fall wäre das int.
0xFF ist schon ein int, da passiert also nichts
Aber tmp. tmp ist ein char. Ein signed char. Und da in 0xFF das MSB
gesetzt ist, ist das eine negative Zahl (nämlich -1). Wird diese auf 16
Bit (die Länge eines int auf dem avr-gcc) erweitert, wird daraus 0xFFFF
(ebenfalls -1, aber diesmal als int)
Und damit lautet der Vergleich, wenn wir mal die Werte einsetzen und für
alles 16-Bit Hex Schreibweise benutzen:
if( 0xFFFF == 0x00FF )
Tja. Und da kann man jetzt lange warten. 0xFFFF und 0x00FF werden
niemals gleich sein.
mit unsigned char anstelle von char, so wie man es benutzt wenn man
einfach nur mit Bytes zu tun hat, wär das nicht passiert.
Markus schrieb:
>> Schmarrn. 0xFF ist schon char.>> Nein, ist es nicht. char ist beim avr-gcc signed. Demnach wäre 0xff> schon short.
Nein ist es nicht.
Karl heinz Buchegger schrieb:
> Wenn man aber von Bytes redet, ist char einfach der falsche Datentyp.
Das mußt Du nicht mir sagen, sondern den Entwicklern des C-Standards
Die habe das mit den negativen Buchstaben verbrochen.
Und da man ja immer die heilige Kompatibilitäts-Kuh durchs C-Dorf
treiben muß, wird das auch weiterhin Milliarden Programmierer zur
Verzweiflung bringen.
> Für Bytes benutzt man immer unsigned char.> Dann passieren solche Probleme nicht.
Allerdings wird man dann jedesmal vom AVR-GCC doof angemotzt, sobald man
ne String-Funktion aufruft (aus der string.h, stdio.h, ...).
Da hilft dann nur, alle Stringfunktionen zu casten.
Oder sich ne "ustring.h" schreiben.
Peter
Peter Dannegger schrieb:
>> Für Bytes benutzt man immer unsigned char.>> Dann passieren solche Probleme nicht.>> Allerdings wird man dann jedesmal vom AVR-GCC doof angemotzt, sobald man> ne String-Funktion aufruft
Ist ja auch OK. Eine Stringfunktion benutzt keine Bytes, sondern chars
(darstellbare Zeichen).
In aller Regel gibt es bei den EA-Operationen genau einmal einen
Übergang zwischen char und uint8_t, beim Übergang zwischen der
internen Zeichendarstellung (char) und dem Hardwareregister (uint8_t).
Dort braucht man dann einen typecast. Alles andere kann typenrein
arbeiten.
Bei C++ ist der Compiler noch pingeliger und besteht darauf, dass
man char, signed char und unsigned char als drei voneinander
verschiedene Datentypen behandelt. Bei C ist ein Programm, das
dies nicht tut, ,,nur'' nicht mehr ``strictly conforming'', d. h.
sein Verhalten hängt von Dingen ab, die ``implementation-defined''
sind.
Peter Dannegger schrieb:
> Das mußt Du nicht mir sagen, sondern den Entwicklern des C-Standards> Die habe das mit den negativen Buchstaben verbrochen.
Ob "char" mit oder ohne Vorzeichen arbeitet, das ist ist im C-Standard
keineswegs definiert.
Das haben letztlich die Leute von DEC verbrochen, die der PDP-11 eine
automatische Vorzeichenerweiterung bei Byteverarbeitung verpasst haben.
Und diese PDP-11 war über eine recht lange Zeit die Standardplattform
für Unix und somit für C.