Subtraktion zweier uint8 geht schief?

Gast #2272207
Lesenswert?

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
#2272223
Lesenswert?

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.
Gast #2272228
Lesenswert?

@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.
#2273011
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren