Forum: PC-Programmierung ergebnis kann negativ werden, obwohl nur uint8_t verwendet wird


von Lars (Gast)


Lesenswert?

Guten morgen,

ich habe mal eine frage zum casten in c
1
#define OFFSET 120
2
3
uint8_t a;
4
uint8_t b;
5
uint8_t c;
6
uint8_t d;
7
8
a = 10;
9
a = 10;
10
a = 10;
11
a = 10;
12
13
if((a + b + c + d - OFFSET) < 0)
14
{
15
   ...
16
}

alles (bis auf das OFFSET) ist uint8_t.
uint8_t kann ja eigentlich nicht <0 werden.
Dennoch wird die Bedingung erfüllt. Sollte man die einzelnen dennoch auf 
int8_t casten?

von Dirk B. (dirkb2)


Lesenswert?

Der Ausdruck beim if wird in als int berechnet.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?


von (prx) A. K. (prx)


Lesenswert?

Lars schrieb:
> Sollte man die einzelnen dennoch auf int8_t casten?

Nur wenn du mit Maschinen rechnen musst, deren Pre-ANSI-C Compiler seit 
35 Jahren nicht mehr renoviert wurde.

Wenn du allerdings von "uint8_t" zu "unsigned" wechselst, wird dir 
mancher Compiler die ganze Abfrage wegoptimieren. Denn dann kann es 
unabhängig von eingesetzten Werten wirklich nicht negativ werden.

: Bearbeitet durch User
von P. S. (namnyef)


Lesenswert?

Unsigned und signed in solch einem Ausdruck zu mischen ist selten eine 
gute Idee, da das Ergebnis wegen der Promotion-Rules nicht immer 
offensichtlich ist und damit eine schöne Quelle für Bugs darstellt.

: Bearbeitet durch User
von Lars (Gast)


Lesenswert?

Μαtthias W. schrieb:
> Und zum nachlesen
>
> https://stackoverflow.com/questions/46073295/implicit-type-promotion-rules
>
> Matthias

Aber wenn ich mir dort mal das 2.Beispiel ansehe, verstehe ich es wieder 
nicht, wie die Bedingung erfüllt werden kann.
1
int main(){
2
    unsigned int a = 1;
3
    signed int b = -2;
4
    if(a + b > 0)
5
        puts("-1 is larger than 0");
6
        printf("%u\n", a+b);
7
}
1
-1 is larger than 0
2
42949672957
hier ist das Ergebnis zwar nicht max uint8, aber max uint32. Welches 
aber auch nicht negativ ist.

von (prx) A. K. (prx)


Lesenswert?

Hier wird die Rechnung in unsigned durchgeführt, da "signed int" und 
"unsigned int" gleich gross sind und nicht erweitert werden. Da wird 
stets in "unsigned" gerechnet, kann also zwar 0 werden, aber nicht 
negativ.

Obacht: "uint32_t" und "unsigned" können verschieden sein. "uint8_t" 
wird aber immer kleiner als "unsigned" sein.

: Bearbeitet durch User
von Hey (Gast)


Lesenswert?

Versuche mal
Printf(„s = %s\n“, a+B)
Dann mit %d %f %c %x %ld %l ... usw. schaue mal was da allgemein so 
rauskommt
If((uint8_t) (a+b) > 0) - geht das ?

Anscheinend castet if intern auf int


Ist wirklich interessant habe selbst leider keine Ahnung - sorry
Viel Erfolg Hast hoffentlich schnell eine Lösung

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.