unerwartetes Verhalten von printf

Gast #1576749
Lesenswert?

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

5
int var;
6

7
int main( ){
8

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

11
  var = 6;
12
  printf("%f\n", var);
13
  printf("%i\n", var);
14

15

16
  system("PAUSE");
17
  return 0;
18

19
}
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
#1576795
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.
Gast #1576806
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
#1576819
Lesenswert?

1
klaus@a64a:~ > gcc -Wall t.c
2
t.c: In function ‘main’:
3
t.c:12: warning: format ‘%f’ expects type ‘double’, but argument 2 has type ‘int’
4
klaus@a64a:~ > gcc -v
5
Using built-in specs.
6
Target: i486-linux-gnu
7
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
8
Thread model: posix
9
gcc version 4.3.2 (Debian 4.3.2-1.1)
#1576822
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.
Gast #1576838
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
#1576867
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.
Gast #1576910
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
Gast #1577160
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

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