[C] Was passiert bei nicht eingebundener header-datei

MastaZulu

Ensign
Registriert
Aug. 2002
Beiträge
207
Hi,
hab da ne Frage:

wenn man jetzt vergisst, z.b. bei verwendeter sqrt() - Funktion die Header-Datei <math.h> einzubinden, und dann den wert z.b. von sqrt(2.0) ausgeben lässt, dann kommt ja ein falsches ergebnis (logischerweise) raus. aber warum kommt überhaupt ein ergebnis raus und warum die 1073742463.00 ?

Code:
#include <stdio.h>

main ()
  {
	double wurzelZwei;
	
	wurzelZwei = sqrt(2.0);
	
	printf("Wurzel 2: %3.2lf\n", wurzelZwei);
  }

Danke im Voraus

MastaZulu
 
c geht davon aus, dass wenn man keinen expliziten rückgabetyp einer fkt angeben hat, dass diese einen int zurück liefert und konvertiert daher von int zu double, was zu dem von dir beschriebenen ergebnis führt.
 
Und dein Compiler zeigt dir eine Warnung an, die dir genau das von ghorst beschriebene Verhalten mitteilt.
Und Warnungen sind genau so wichtig wie echte Fehlermeldungen. Also niemals eine Warnung ignorieren.
 
Sofern math.h nicht irgendwo von stdio.h gezogen wird, geht der C-Compiler davon aus, dass du mit ... sqrt( ...) implizit eine Funktion des Namens sqrt deklarierst, die einen double bekommt und einen double zurückgibt. Anscheinend wird die Mathebibliothek dazu gelinkt und der Linker kann deine sqrt-Funktion, die eigentlich unresolved ist, doch wieder zuordnen - und zwar sqrt aus der libm.

Warum da diese Zahl rauskommt ist mir allerdings unklar. Das liegt möglicherweise an deinem printf. %lf ist kein gültiger Formatspezifizierer nach dem C-Standard. (das l passt nicht zum f) Möglicherweise glaubt der Compiler, der übergebene double sei ein long double und interpretiert die binäre Information falsch.

Diese Technik, den passenden Header nicht zu inkludieren, sondern nur eine implizite Deklaration auf die Funktion zu machen war zu C-Zeiten übrigens eine beliebte (und gültige) Technik, um Abhängigkeiten, die man sich aus anderen Headern zieht, zu minimieren (allerdings auch eine extrem fehlerträchtige). Unter C++ wurde dieses Verhalten übrigens abgeschafft.


Nachtrag: Um zu schauen, ob das printf das Problem ist, schau dir mal den Inhalt von wurzelZwei nach dem Aufruf von sqrt im Debugger an.
 
Zuletzt bearbeitet:
7H3 N4C3R schrieb:
Sofern math.h nicht irgendwo von stdio.h gezogen wird, geht der C-Compiler davon aus, dass du mit ... sqrt( ...) implizit eine Funktion des Namens sqrt deklarierst, die einen double bekommt und einen double zurückgibt. Anscheinend wird die Mathebibliothek dazu gelinkt und der Linker kann deine sqrt-Funktion, die eigentlich unresolved ist, doch wieder zuordnen - und zwar sqrt aus der libm.
das mit sqrt tut c genau so nicht. es wird impliziert deklariert, das ist richtig, aber standardrückgabe wert ist ein int und nix anderes. daher kann man bei dem rückgabewert int die deklaration eigentlich weg lassen, sollte es aber nie mals tuen.
der linker schmeißt es immer dann mit rein, wenn es keine eigenständige math-lib gibt. das z.b. bei windows der fall.
 
Puh, dann ist es mir aber irgendwie unerklärlich, wie er Linker int sqrt( double) gegen double sqrt( double) matchen kann. Genau diese Eigenarten sind aber auch ein Grund, warum ich C nicht mag ^^
 
du kannst auch einen int auf einen double zu weisen und genau das macht c da. es nimmt implizit an, dass es sich um fkt. mit dem rückgabe wert int handelt, und fügt dann, damit es ist ein double und kein int mehr ist, einen ebenfalls impliziten cast ein.
der implizite cast ist voll ok, das macht c und alle andere sprachen ständig. aber mit der implizite funktionsdeklaration haben die erfinder von c den programmiern einst einen bäredienst erwiesen. man braucht den käse schlicht nicht, da c sehr gute möglichkeiten zur forward deklarationen hat.
 
Zurück
Oben