Forum: Compiler & IDEs uint32_t - stolperfalle ?


von Stefan Sczekalla (Gast)


Lesenswert?

hi,

ich habe einige variablen unit32_t deklariert - das progarmm scheint
sich aber so zu verhalten als wenn es signed int16 wären - muss man da
z.b. in if-Abfragen casten oder so ?

grüße,

Stefan

von Stefan Sczekalla (Gast)


Lesenswert?

... um die ingrid zu machen -

(...)                    Distance = (uint32_t)(3700 + 3800 * (NextTrak -
CurrentTrak - 1));
              ltoa(Distance,buffer,10);
                    lcd_puts(buffer);
(...)

ich erhalte die anzeige eines negativen werte sobald sich Distance
größer als 32768 berechnet  .... erwartet hätte ich 32769 ... und höher


bin etwas ratlos ... weil selbst Casten scheinbar nicht hilft.

alle Variablen sind uint32_t bzw. unsigned long deklariert.

ich arbeite mit der winavr Ausgabe vom Februar diesen Jahres.

Grüße,

Stefan

von Stefan Sczekalla (Gast)


Lesenswert?

hrmpppfff ...

Distance = (uint32_t) 3700 + (uint32_t) 3800 * (NextTrak - CurrentTrak
- (uint32_t) 1);

so gehts jetzt - nur - worin liegt denn für den Compiler der echte
unterschied zu:

Distance = (uint32_t)(3700 + 3800 * (NextTrak -
CurrentTrak - 1));

Warum convertiert er hier die Constanten nicht passend ?

Grüße,

Stefan

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Schreib' hinter die Konstanten ein großes 'L' oder besser noch ein
'UL'. Damit teilst Du dem Compiler mit, daß diese Konstanten long
bzw. unsigned long sind.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> so gehts jetzt - nur - worin liegt denn für den Compiler der echte
> unterschied zu ... Warum convertiert er hier die Constanten nicht
> passend?

Weil er nicht muss.  Die argument promotion in Ausdrücken erfolgt
immer paarweise, d.h. wenn eine der beiden Seiten eines binären
Operators einen ,,größeren'' Typ hat als die andere Seite, dann wird
die andere Seite zuvor auf diesen Typ erweitert.  Konstanten, die groß
genug sind, um nicht mehr in `int' zu passen, werden dabei
automatisch
zuerst als `unsigned int' genommen, wenn das nicht mehr genügt als
`long' usw.  Deine Konstanten passen aber alle bequem in ein `int'.
Würdest du nur eine davon mit einem UL-Suffix versehen, wäre sie aber
unsigned long, und damit müsste der Rest des Ausdrucks vor der
Rechnung ebenfalls dahin konvertiert werden.  Die (unit32_t) typecasts
tun natürlich dasselbe.

von Stefan Sczekalla (Gast)


Lesenswert?

Vielen Dank für die Erleuchtung.

Grüße

Stefan (db8fw)

von Jens (Gast)


Lesenswert?

Warum nicht einfach so?

unsigned long varaible;

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Weil du rein gar nichts von obiger Diskussion verstanden hast.

Die variable war korrekt deklariert, nur der Ausdruck auf der
rechten Seite wurde mit dem falschen Datentyp berechnet.  Warum,
das steht alles im Thread oben drin...

von Jens (Gast)


Lesenswert?

> Weil du rein gar nichts von obiger Diskussion verstanden hast.

Kannst du so nicht sagen denn zugegebenermaßen habe ich die Diskussion
nur ansatzweise gelesen. Daher vergebt mir bitte meinen Beitrag...



P.S.: Warum unit32_t statt "unsigned long" habe ich nie verstanden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Warum uint32_t statt "unsigned long"?

Weil sizeof (unsigned long) nicht unbedingt 32 ist.

Das kann, je nach Maschine, auch einen ganz anderen Wert annehmen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

 Korrektur 

Weil sizeof (unsigned long) nicht unbedingt 4 ist.


(und einen Trottelpunkt von meinem Konto abziehen)

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.