Fragen zu Warnings



  • Hallo,

    ich versuche gerade alle Warnings aus meinem Programm zu beseitigen. Allerdings will ich dabei auch was lernen bzw. bei anderen weiß ich garnicht, was genau das Problem ist:

    In dieser Zeile:

    D3DXMatrixPerspectiveFovLH(projMatrix, D3DXToRadian(fov), viewRatio, nearPlane, farPlane);
    

    sagt er:

    Warning 1 warning C4244: 'argument' : conversion from 'double' to 'FLOAT', possible loss of data

    Wenn ich den 2. Paramter auf float caste, ist das Warning weg (die Funktion will eine Matrix und 4 doubles).
    Ich verstehe jedoch das Warning nicht, da fov vom Typ float ist und das Makro D3DXToRadian so aussieht:

    define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f))
    

    D3DX_PI ist ebenfalls ein float.
    Es wird doch ausschließlich per floats gerechnet, wieso kommt dann am Ende ein double raus?



    1. Ich bekomme dutzende Warnings, dass Funktionen (sprintf, gets etc.) deprecated sind:

    Warning 12 warning C4995: 'sprintf': name was marked as #pragma deprecated d:\microsoft visual studio 8\vc\include\cstdio 37

    Allerdings benutze ich NIRGENDS diese Funktionen. Wenn ich einen Doppelklick auf das Warning mache, springt er in den entsprechenden Header (hier also zb. in cstdio.h). Aber auch diesen Header binde ich nicht mal ein.
    Wieso bekomme ich dann deprecated warnings? 😕



  • Wenn ich den 2. Paramter auf float caste, ist das Warning weg (die Funktion will eine Matrix und 4 doubles).
    Ich verstehe jedoch das Warning nicht, da fov vom Typ float ist und das Makro D3DXToRadian so aussieht:

    Also das ist ein sehr schönes Beispiel, warum man Defines vermeiden sollte. Sie sind nicht Typsicher. Der Compiler weiss ja nicht, was das für ein Typ war, den du übergeben hast und nimmt schlussenldich einfach an, was am besten passt. Hier wegen der Genauigkeit double.

    Wegen den anderen Fehler. Was für Header hast du da so?



  • drakon schrieb:

    Also das ist ein sehr schönes Beispiel, warum man Defines vermeiden sollte. Sie sind nicht Typsicher. Der Compiler weiss ja nicht, was das für ein Typ war, den du übergeben hast und nimmt schlussenldich einfach an, was am besten passt. Hier wegen der Genauigkeit double.

    Aber der Compiler sieht doch das Makro garnicht. Für ihn steht da einfach ein langer Ausdruck mit lauter Floats. Wie zur Hölle kann ein Ausdruck mit lauter Floats zu double werden? 😕



  • Der Compiler sieht das Makro nicht, richtig. Aber der Praeprozessor ersetzt es stumpf und ohne hinzuschauen, wenn beispielsweise D3DX_PI nicht als float-literal definiert ist sondern als double-literal (oder als eine funktion die irgendwo einen double uebergeben bekommt und deshalb auch einen double zurueckgibt), dann sieht der Compiler nach dem expandieren des Makros ein float*double/float stehn, was ein double ergibt.
    Was das sprintf angeht: du selbst bindest die cstdio vielleicht nicht ein, aber eventuell macht das einer der Header aus der Bibliothek die du da benutzt (wenn die so mit #define s um sich werfen schrecken sie auch vor sprintfs nicht zurueck)



  • pumuckl schrieb:

    wenn beispielsweise D3DX_PI nicht als float-literal definiert ist sondern als double-literal (oder als eine funktion die irgendwo einen double uebergeben bekommt und deshalb auch einen double zurueckgibt), dann sieht der Compiler nach dem expandieren des Makros ein float*double/float stehn, was ein double ergibt.

    Ähmm... aber ich hab doch jetzt bereits 2 mal geschrieben, dass in dem Ausdruck nur Floats vorkommen.
    Hier nochmal die Makros:

    #define D3DX_PI    ((FLOAT)  3.141592654f)
    #define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f))
    

    pumuckl schrieb:

    Was das sprintf angeht: du selbst bindest die cstdio vielleicht nicht ein, aber eventuell macht das einer der Header aus der Bibliothek die du da benutzt (wenn die so mit #define s um sich werfen schrecken sie auch vor sprintfs nicht zurueck)

    Hm ja, das scheint so zu sein. Gibt es eine elegantere Methode als in jede .cpp Datei vorm einbinden des headers ein
    #pragma warning (disable: 4995 4996)
    zu schreiben?



  • warnings schrieb:

    Gibt es eine elegantere Methode als in jede .cpp Datei vorm einbinden des headers ein
    #pragma warning (disable: 4995 4996)
    zu schreiben?

    Mach dir einen Header der den Header der besagten Bibliothek einbindet, und in diesem einen header machst du das #pragma. In deinem Projekt bindest du dann den ein statt direkt den Bibliotheksheader zu nehmen.



  • Ähmm... aber ich hab doch jetzt bereits 2 mal geschrieben, dass in dem Ausdruck nur Floats vorkommen.
    Hier nochmal die Makros:

    Ich habe es doch auch erklärt. Musst mal schauen, WAS der Präprozessor macht.

    #define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f))
    

    Wird ev. zu dem da:

    0.012348723498234234324980
    

    Und wenn du das so mal einem float zuweisen willst, wird er dir ebenfalls eine Warnung geben, dass da double zu float konvertiert wird. Weil double hald genauer, also grösser ist, als float.
    Und wenn der Compiler nicht weiss, was für ein Datentyp es ist, wird einfach mal der passendste angenommen. (Hier hald double)



  • drakon schrieb:

    Und wenn der Compiler nicht weiss, was für ein Datentyp es ist, wird einfach mal der passendste angenommen. (Hier hald double)

    Der Compiler weiß aber immer, was fuer ein Datentyp vorliegt. Und der Präprozessor kann aus einem Makro auch nicht machen, was er will...



  • drakon schrieb:

    Ähmm... aber ich hab doch jetzt bereits 2 mal geschrieben, dass in dem Ausdruck nur Floats vorkommen.
    Hier nochmal die Makros:

    Ich habe es doch auch erklärt. Musst mal schauen, WAS der Präprozessor macht.

    #define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f))
    

    Wird ev. zu dem da:

    0.012348723498234234324980
    

    Nein, da liegst du falsch. Das Makro wird definitiv nicht zu einer einzigen Zahl. Das Makro wird einfach zu dem Ausdruck der da oben steht (außer PI natürlich, da wird auch eine Zahl stehen) expandiert. Ich habe dann also einen Ausdruck, der nur aus floats besteht.
    Die einzige logische Erklärung die ich mir vorstellen könnte ist, dass generell bei Float Arithmetik in Doubles gerechnet wird.
    Aber das ist nur eine Vermutung. 😞



  • Sorry, habe was anderes im Kopf gehabt.

    Hmm, Also ich habe den Ausdruck jetzt mal ausprobiert und das einzige, was mit aufgefallen ist, ist das FLOAT (also gross geschrieben).

    Hmm, was hast du für einen Compiler?



  • drakon schrieb:

    Hmm, Also ich habe den Ausdruck jetzt mal ausprobiert und das einzige, was mit aufgefallen ist, ist das FLOAT (also gross geschrieben).

    FLOAT ist ein typedef auf float.

    drakon schrieb:

    Hmm, was hast du für einen Compiler?

    Visual Studio 2005.

    Leute, das kann doch nicht sein, dass dazu keiner ne Antwort hat. Gibts doch ein paar, die den Standard auswendig kennen^^



  • Also ich kann den Fehler nicht nachvolziehen. (VC++ 08).

    Ich bekomme keine Warnung, nichts.

    Auf welchem Warning Level bist du?



  • Wurde eventuell dein eigenes Makro moochmal übergebügelt (also das PI Dingens)?

    MfG Kimmi



  • Übergebügelt? oO



  • warnings schrieb:

    Übergebügelt? oO

    Jo. wenn das Makro woanders nochmal definiert wurde steht da nichtmehr das was du denkst. Schreib mal eine Zeile davor

    assert(false && D3DXToRadian(fov));
    

    Wenn du das Programm dann laufen lässt müsste er dir die Zeile dann mit dem hoffentlich expandierten makro um die Ohren werfen, dann siehste evtl was der Compiler da zu sehen bekommt.



  • Sowas garantiert dir, dass dein Macro angezogen wird, sofern niemand danach auf die gleiche Idee kommt:

    #ifdef FOO
    #  undef FOO
    #endif
    
    #define FOO meins
    

    Nur kann das halt auch jeder sonst machen -> nicht sicher. Schau dir doch einfach den Output deines Preprozessors an.

    MfG Kimmi


Anmelden zum Antworten