Hallo, ich versteh da was nicht, vielleicht helft ihr mir auf die Sprünge. (Der Code unten handelt von einem Sekundenzähler, der einen Minutenzähler inkrementieren soll.) Beispielcode: uint8_t a; // SekundenZähler uint8_t b; // SekundenZählerStempel a = 59; b = 255; if( (a - b) == 60) { ...minutenzähler hier hochzählen... } Der Code oben führt leider nicht zur korrekten Inkrementierung, während dieser hier funktioniert. if( (uint8_t)(a - b) == 60) { ...minutenzähler hier hochzählen... } Sieht so aus als ob in der oberen Subtraktion nicht mit uint8 Typen gearbeitet wird, da es mit dem Cast auf uint8 funktioniert es. Meine Frage: warum muss ich dem Compiler extra sagen, dass er auf uint8 beschränken muss, obwohl alle beteiligten Typen ja uint8 sind? Gruß, Arian
Arian schrieb: > a = 59; > b = 255; > > if( (a - b) == 60) > { > ...minutenzähler hier hochzählen... > } uint8_t ist unsigned, also vorzeichenlos unt geht von 0...255 59-255 ist aber negativ. hubert
Arian schrieb: > Meine Frage: warum muss ich dem Compiler extra sagen, dass er auf uint8 > beschränken muss, obwohl alle beteiligten Typen ja uint8 sind? Weil der C-Standard vorschreibt, dass alle Berechnungen/Vergleiche mindestens in int zu erfolgen haben. Im ersten Beispiel werden a und b nach int gewandelt, subtrahiert und dann das int-Ergnebnis mit 60 verglichen. Im zweiten Fall läuft es so: a und b werden nach int gewandelt und subtrahiert, das int-Ergebnis wird dann wegen des Cast auf uint8_t gestutzt, das wird dann wieder nach int gewandelt und mit 60 verglichen.
@Hubert: unsigned kann man voneinander subtrahieren, auch wenn der Subtrahend größer als der Minuend ist. In diesem Fall wird die Differenz trotzdem korrekt berechnet - vorausgesetzt es wird auch im richtigen Typ (uint8) gerechnet. @Stefan Ernst: Besten Dank für die Erklärung, sehr hilfreich. Das heißt für mich, wenn ich in Zukunft Zähler mit Überlauf anlege, und der Bereich 0..127 ausreicht, bin ich mit einem signed besser dran, weil ich dann in Subtraktionen usw. nicht an casts denken muss.
Arian schrieb: > Das heißt für mich, wenn > ich in Zukunft Zähler mit Überlauf anlege, und der Bereich 0..127 > ausreicht, bin ich mit einem signed besser dran, ... Signed-Überlauf ist undefined.
Johann L. schrieb: > Signed-Überlauf ist undefined. D.h. ich komm um den Cast nicht rum. Wundert mich dass ich das Problem nur beim ATMEL merke. Eventuell kümmern sich andere Compiler wie der von TI implizit darum.
Arian schrieb: > Wundert mich dass ich das Problem nur beim ATMEL merke. Eventuell > kümmern sich andere Compiler wie der von TI implizit darum. Ein Compiler, der sich nicht so verhält, wie du im ersten Posting schilderst, der arbeitet nicht korrekt. Es gibt Compiler für 8-Bit Maschinen, die optional oder per default die implizite int-Konvertierung unterlassen. Das entspricht dann nicht dem Standard, erzeugt aber kürzeren Code.
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.