www.mikrocontroller.net

Forum: PC-Programmierung unerwartetes Verhalten von printf


Autor: Yaro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
ich bin beim Programmieren zufällig auf folgendes Problem gestoßen:
Beim Ausführen dieses Codes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int var;

int main( ){

  printf("%f\n", 2345.0f);

  var = 6;
  printf("%f\n", var);
  printf("%i\n", var);


  system("PAUSE");
  return 0;

}
kommt das unerwartete Ergebniss: 2345 \n 2345 \n 6    raus. Eigentlich
hätte ich 2345 \n 0 \n 6   oder ähnliches erwartet.
Wie kommt soetwas?

Gruß, Yaro

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wieso 0?

Es hat keinen Sinn, eine int-Variable mit %f auszugeben.
Der gcc würdigt das zumindest in der Einstellung -Wall mit
einer Warnung, die du offenbar ignorierst.

Mit %i oder %d wird int ausgegeben, mit %f, %e und %g
double (bzw. float).

Alles andere ist Unfug, und jede Ausgabe nichts, was ich als
unerwartet bezeichnen würde.

Autor: Yaro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es hatte Anfangs damit zutun, dass ich Probleme mit globalen und lokalen 
Variablen hatte, die ich zufällig gleich benannt habe (debug-Variablen), 
die sich dann überschatteten... Ich hab versucht das mit printf 
auszugeben und da kamen richtig verwirrende Sachen bei raus...
Wenn der Compiler mir eine Warnung angezwigt hätte, wäre es ja kein 
Problem gewesen, aber das hat er nicht (habe wohl einen zu alten (gcc))

Gruß, Yaro

Autor: Yaro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Scheint so, als ob das ein Problem mit meiner Programmierumgebung wäre, 
ich kriege überhaupt keine Warnungen angezeigt...

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
klaus@a64a:~ > gcc -Wall t.c
t.c: In function ‘main’:
t.c:12: warning: format ‘%f’ expects type ‘double’, but argument 2 has type ‘int’
klaus@a64a:~ > gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.2-1.1' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-cld --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.3.2 (Debian 4.3.2-1.1) 

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem rührt daher, daß printf nicht weiß, was man ihm
übergibt - es sieht nur ein Bitmuster im Speicher und vermutet
anhand der Formatbeschreibung %f, daß es eine double ist.
Also wird das Bitmuster entsprechend ausgegeben.

Das ist etwa, als ob du einen Zeiger auf eine int hast, den
Zeiger mit einem cast zu einem Zeiger auf double vergewaltigst
und darüber aus dem Bitmuster der int eine double liest, die
dort nie stand.

Autor: Yaro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hätte dann aber nicht zufolge, dass er 2345 (das, was ich vorher 
schonmal ausgegeben hatte) ausgibt. Dann würde er mit großer 
Wahrscheinlichkeit irgendeine andere Zahl, oder NaN ausgeben.
Scheint, dass das in der Funktion selber irgendwie anders gehandhabt 
wird.

Gruß, Yaro

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kann auch einfach daran liegen, daß ein float- bzw.
double-Parameter anders übergeben wird als eine int; z.B.
in einem FPU-Register (je nach Compiler).
Bei dem zweiten Aufruf mit der int wird das FPU-Register
dann nicht verändert und der Wert vom ersten Aufruf liegt
da noch.
Müsste man halt mal den erzeugten Maschinencode anschauen,
wenn es dich interessiert.

Sonderlich wichtig finde ich es aber eigentlich nicht,
weil es einfach falscher Quelltext ist und der je nach
Rechner und Compiler beliebigen Schwachsinn produzieren
darf.

Autor: Yaro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ähnlich wird es wohl sein.
Sich den erzeugten Code von printf anzuschauen sollte relativ 
kompliziert werden, da printf relativ unübersichtlich (schon in C) 
geschrieben ist.
Ich habe jetzt die Warnungen auch angeschaltet und sollte damit dann 
keine größeren Probleme mehr bekommen.

Danke für deine Hilfe!
Gruß, Yaro

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitte.

Du musst ja nicht den Code von printf anschauen, es reicht
der Aufruf in deinem Quelltext. Dazu habe ich aber heute auch
keine Lust, mehr ich habe noch Hunger.

Autor: D. I. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yaro schrieb:
> Es hatte Anfangs damit zutun, dass ich Probleme mit globalen und lokalen
> Variablen hatte, die ich zufällig gleich benannt habe (debug-Variablen),
> die sich dann überschatteten... Ich hab versucht das mit printf
> auszugeben und da kamen richtig verwirrende Sachen bei raus...
> Wenn der Compiler mir eine Warnung angezwigt hätte, wäre es ja kein
> Problem gewesen, aber das hat er nicht (habe wohl einen zu alten (gcc))
>
> Gruß, Yaro

ich meine dafür gibt es -Wshadow dann wird dir das angezeigt, jedenfalls 
gibts ein flag dafür

Autor: Yaro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs jetzt auch gefunden, mache das nun mit -Wall

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.