von uint32_t nach int casten

#3278775
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.
Gast #3278791
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.
#3278816
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.
#3278827
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.
#3278830
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.
#3278835
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.
#3278837
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...
#3278845
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.
Gast #3278959
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.
#3278981
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.
#3279460
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.
Gast #3279851
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.
Gast #3279859
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é
Moderator #3279942
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.

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