Forum: Compiler & IDEs von uint32_t nach int casten


von Joachim .. (joachim_01)


Lesenswert?

Moin,
eigentlich ist mir das ja schon fast peinlich, aber...
1
    uint32_t Engine_Speed = 0;
2
3
    Engine_Speed = (int)Engine_Speed;
4
    sprintf( buf1,"%i", Engine_Speed);
obwohl ich brav gecasted habe bekomme ich eine Warnung:
Warning  1  format '%i' expects argument of type 'int', but argument 3 
has type 'uint32_t' [-Wformat]

int Engine_Speed = 0; anstatt uint32_t Engine_Speed = 0;
geht wie üblich fehlerfrei.

von Peter II (Gast)


Lesenswert?

was für eine Platform? wie gross ist denn bei dir ein int?

von SpieleJupp (Gast)


Lesenswert?

du musst eine int variable deklarieren. und dieser dann denn gecasteten 
Wert zuweisen

von SpieleJupp (Gast)


Lesenswert?

den nicht denn :-(

von Daniel (Gast)


Lesenswert?

Hallo,
mach den cast doch in der Ausgabe.
1
 uint32_t Engine_Speed = 0;
2
    sprintf( buf1,"%i",(int)Engine_Speed);

von Klaus B. (nuccleon)


Lesenswert?

> Moin,
> eigentlich ist mir das ja schon fast peinlich, aber...

Ich lass die Aussage mal so stehen...

Wie wärs denn mit:
1
uint32_t Engine_Speed = 0;
2
3
sprintf( buf1,"%i", (int)Engine_Speed);

von chris (Gast)


Lesenswert?

uint32_t Engine_Speed = 0;

    Engine_Speed = (int)Engine_Speed;
    sprintf( buf1,"%i", Engine_Speed);

klar ist das falsch,
    Engine_Speed = (int)Engine_Speed;
Engine_Speed bleibt uint32_t, du wandelst nur Engine_Speed in (int) und 
dann wieder in uint.

Wenn du dies machst:
   sprintf( buf1,"%i", (int)Engine_Speed);
dann gibt der Compiler keinen Fehler aus, aber eigentlich gibt es auch
unsigned int für (s)printf und eigentlich solltest du dies verwenden.

von Joachim .. (joachim_01)


Lesenswert?

>du musst eine int variable deklarieren. und dieser dann denn gecasteten
>Wert zuweisen
Mach ich das denn nicht mit der Zeile:
uint32_t Engine_Speed = 0;
?



>Hallo,
>mach den cast doch in der Ausgabe.
Warnung ist weg. Danke.

von Rene H. (Gast)


Lesenswert?

uint32_t != int

uint32_t = unsigned
int      = signed

Grüsse,
René

von Joachim .. (joachim_01)


Lesenswert?

>aber eigentlich gibt es auch
>unsigned int für (s)printf und eigentlich solltest du dies verwenden.

sprintf( buf1,"%ui", Engine_Speed);
>Das geht nicht, gleiche Warnung. System hier ist 32-bit.

von Peter S. (psavr)


Lesenswert?

>>du musst eine int variable deklarieren. und dieser dann denn gecasteten
>>Wert zuweisen
>Mach ich das denn nicht mit der Zeile:
>uint32_t Engine_Speed = 0;
>?
Nein du deklarierst einen 'uint_32t' das ist nicht das gleiche wie 'int'

von Karl H. (kbuchegg)


Lesenswert?

Joachim ... schrieb:

>     uint32_t Engine_Speed = 0;
>
>     Engine_Speed = (int)Engine_Speed;

Das ändert aber nichts.
Die Variable Engine_Speed ist auch danach immer noch vom Datentyp 
uint32_t

Eine Variable ändert ihren Datentyp nicht mehr. Sie kriegt ihn bei der 
Defintion der Variablen und behält ihn danach bei, bis sie zerstört 
wird. Du kannst diser Variablen zuweisen was du willst, das ändert 
nichts daran, dass die Variable (bei dir) ein uint32_t ist. Alles was du 
zuweist wird automatisch immer zu einem uint32_t. Denn so ist die 
Variable ja definiert. In C passen sich die Datentypen von Variablen 
nicht an das an, was man ihnen zuweist. Sonst bräuchte man ja von vorne 
herein Variablen überhaupt keinen Datentyp geben, wenn das dann sowieso 
dadurch geregelt wird, was ihnen zugewiesen wird.

von chris (Gast)


Lesenswert?

Dann hat dein Compiler ein Problem,
Engine_Speed=100;
sprintf( buf1,"%ui", Engine_Speed);
Ausgabe wäre 100i !!!
dies ist das richtige:
sprintf( buf1,"%u", Engine_Speed);

von Joachim .. (joachim_01)


Lesenswert?

>Eine Variable ändert ihren Datentyp nicht mehr. Sie kriegt ihn bei der
>Defintion der Variablen und behält ihn danach bei, bis sie zerstört
>wird.

Ok, ich glaub wir haben jetzt eine Lücke in meinem Kopf geschlossen. 
D.h. also, in
sprintf( buf1,"%i", (int)Engine_Speed);
wird "nur zur Übergabe" aus dem uint32_t ein int.

von Karl H. (kbuchegg)


Lesenswert?

Joachim ... schrieb:

>>Hallo,
>>mach den cast doch in der Ausgabe.
> Warnung ist weg. Danke.


Ist eigentlich der falsche Weg.
Benutze in der Format Liste die richtigen Kürzel, die zu den Datentypen 
der Argumente passen und nicht umgekehrt caste die Argumente so zurecht, 
so dass sie zur Format-Liste passen.

Einen Cast sollte man nur dann verwenden, wenn es keine andere 
Alternative gibt. Ein Cast ist immer die schlechteste Möglichkeit, ein 
Problem zu lösen. Casts sind sozusagen der Holzhammer, mit dem man alles 
irgendwie passend machen kann - egal ob das nun richtig ist oder nicht.

von Karl H. (kbuchegg)


Lesenswert?

Joachim ... schrieb:
>>Eine Variable ändert ihren Datentyp nicht mehr. Sie kriegt ihn bei der
>>Defintion der Variablen und behält ihn danach bei, bis sie zerstört
>>wird.
>
> Ok, ich glaub wir haben jetzt eine Lücke in meinem Kopf geschlossen.
> D.h. also, in
> sprintf( buf1,"%i", (int)Engine_Speed);
> wird "nur zur Übergabe" aus dem uint32_t ein int.

Exakt.
Und das auch nur, weil du das so befohlen hast, damit dieser int zum %i 
passt.
Würdest du umgekehrt vorgehen und dich fragen welchen Datentyp 
Engine_Speed hat, dann stellst du fest, dass das ein uint32_t ist, auf 
deinem System wohl ein unsigned long. Ergo brauchst du anstelle des %i 
das entsprechende Kürzel welches zu einem unsigned long passt.

von Joachim .. (joachim_01)


Lesenswert?

Hmm. Also die beiden Zeilen hier:
Engine_Speed=100;
sprintf( buf1,"%u", Engine_Speed);


werfen für die Zeile mit sprintf:
Warning  1  format '%u' expects argument of type 'unsigned int', but 
argument 3 has type 'uint32_t' [-Wformat]


Aber wir kommen hier langsam vom Stöckchen zum Zeigchen und sollten das 
Ganze allmählich wegen Geringfügigkeit abbrechen...

von Karl H. (kbuchegg)


Lesenswert?

Joachim ... schrieb:

> Aber wir kommen hier langsam vom Stöckchen zum Zeigchen und sollten das
> Ganze allmählich wegen Geringfügigkeit abbrechen...

Du würdest wesentlich schneller vorankommen, wenn du ein C-Buch hättest. 
Denn da wäre eine Tabelle drinnen, in der die ganzen % Specifier 
aufgeschlüsselt sind. Und nebenbei noch 300 andere Dinge, die man mit 
dem Format-String so anstellen kann.
1
  sprintf( buf1,"%ul", Engine_Speed);


Aber ... du bist nicht der erste, du bist nicht der letzte und du wirst 
auch nicht der letzte sein, der denkt, man könne C mit anlassbezogenem 
Zusammenfragen von Achtelwissen in einem Forum vernünftig lernen. Das 
hat noch nie funktioniert, das funktioniert nicht und das wird auch nie 
funktionieren.

von Jackson (Gast)


Lesenswert?

Was mich an der ganzen Diskussion ein wenig vermisse:
Hat denn auf Deinem µC ein "int" die gleiche Bitbreite wie ein 
"int32_t"?
Hat denn auf Deinem µC ein "unsigned int" die gleiche Bitbreite wie ein 
"uint32_t"?

Auf meinem PIC24 kann ich mit %i nur 16Bit-Werte ausgeben,aber kein 
int32_t.

von Stefan E. (sternst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> dass das ein uint32_t ist, auf
> deinem System wohl ein unsigned long. Ergo brauchst du anstelle des %i
> das entsprechende Kürzel welches zu einem unsigned long passt.
>
> sprintf( buf1,"%ul", Engine_Speed);

Man benutzt Datentypen wie uint32_t ja aber auch, um sich von 
Plattformabhängigkeiten zu befreien. Sich diese über printf-Specifier 
durch die Hintertür wieder rein zu holen, finde ich nicht sehr sinnvoll. 
Und es gibt schließlich einen standardisierten Weg, die 
Plattformunabhängigkeit auch in die printf-Specifier zu übertragen:
1
sprintf( buf1,"%"PRIu32, Engine_Speed);
Man mag über die Ästhetik streiten, aber es ist nun mal der vorgesehen 
Weg, der (meiner Meinung nach) auch Neulingen nahe gebracht werden 
sollte.

von Karl H. (kbuchegg)


Lesenswert?

Stefan Ernst schrieb:

> Plattformunabhängigkeit auch in die printf-Specifier zu übertragen:
>
1
sprintf( buf1,"%"PRIu32, Engine_Speed);
> Man mag über die Ästhetik streiten, aber es ist nun mal der vorgesehen
> Weg, der (meiner Meinung nach) auch Neulingen nahe gebracht werden
> sollte.

Full Ack.
Diese neuen Specifier hab wiederrum ich noch nicht drinnen. :-)
Mea culpa.

von DirkB (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Diese neuen Specifier hab wiederrum ich noch nicht drinnen. :-)

Karl Heinz Buchegger schrieb:
> sprintf( buf1,"%ul", Engine_Speed);

Die alten aber auch nicht. :-)
Es ist "%lu"

u ist das Ausgabeformt
l ist die Größenangabe

von Karl H. (kbuchegg)


Lesenswert?

DirkB schrieb:
> Karl Heinz Buchegger schrieb:
>> Diese neuen Specifier hab wiederrum ich noch nicht drinnen. :-)
>
> Karl Heinz Buchegger schrieb:
>> sprintf( buf1,"%ul", Engine_Speed);
>
> Die alten aber auch nicht. :-)
> Es ist "%lu"
>
> u ist das Ausgabeformt
> l ist die Größenangabe


Ich darf Homer Simpson zitieren: Mist

Da kannst du mal sehen, wie oft ich noch uint32_t und printf zusammen 
verwende. :-)
Auf jeden Fall danke für die Korrektur.

von asdf (Gast)


Lesenswert?

Rene H. schrieb:
> uint32_t != int
>
> uint32_t = unsigned
> int      = signed

Ist es eigentlich vom C Standard zwingend vorgeschrieben, dass "int" 
signed ist? Und ist das auch in der Praxis immer so? Gibt es Compiler 
wo "int" einem "unsigned int" entspricht (oder das per Compiler-Option 
so eingestellt werden kann)?

Ich weiss, dass "char" sowohl signed als auch unsigned sein kann, z.T. 
als Compileroption auswählbar, oder dass z.B. manche Compiler per Option 
erlauben, dass "int" als "short" behandelt wird, usw. Daher meine Frage.

von Rene H. (Gast)


Lesenswert?

asdf schrieb:
> Ist es eigentlich vom C Standard zwingend vorgeschrieben, dass "int"
> signed ist? Und ist das auch in der Praxis immer so? Gibt es Compiler
> wo "int" einem "unsigned int" entspricht (oder das per Compiler-Option
> so eingestellt werden kann)?

Das kann ich nicht mit absoluter Sicherheit sagen, aber meines Wissens: 
ja. Und ich kenne keinen Compiler der aus int einen unsigned macht.

Grüsse,
René

von Yalu X. (yalu) (Moderator)


Lesenswert?

asdf schrieb:
> Ist es eigentlich vom C Standard zwingend vorgeschrieben, dass "int"
> signed ist?

Ja, außer wenn int der Type eines Bitfelds ist. In diesem Fall ist es 
implementation-defined, ob int überhaupt erlaubt ist und wenn ja, ob 
der Typ vorzeichenbehaftet ist. Im Standard spezifiziert sind nur die 
Bitfeldtypen _Bool, signed int und unsigned int.

von Bronco (Gast)


Lesenswert?

1
sprintf( buf1,"%"PRIu32, Engine_Speed);

Weiß jemand zufällig, was "PRI" und "SCN" bedeuten?

von Stefan E. (sternst)


Lesenswert?

Bronco schrieb:
> sprintf( buf1,"%"PRIu32, Engine_Speed);
>
> Weiß jemand zufällig, was "PRI" und "SCN" bedeuten?

PRIntf und SCaNf

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.