M_PI in Release-Mode unbekannt



  • Ich habe eine SDI mit einem CFormView. In der Dokumentenklasse führe ich mehrere Berechnungen aus, bei der ich auch Zahl Pi brauche. Jetzt habe ich in der cpp-Datei meiner Dok-Klasse ein

    #define _USE_MATH_DEFINES
    #include <cmath> //wahlweise auch #include <math.h>
    

    auch nach dem Include der stdafx.h drin. Im Debug-Modus ist das alles kein Problem. Compiliere ich im Release-Modus, dann meckert der Compiler überall da wo ich M_PI verwende (error C2065: 'M_PI': nichtdeklarierter Bezeichner).
    Was mach ich da falsch bzw. gibts dafür eine Erklärung?



  • Ich möchte diesen Beitrag noch mal aufgreifen. Hab jetzt im Quelltext:

    #ifndef M_PI
    	#define M_PI       3.14159265358979323846f
    #endif
    

    eingefügt. Damit lässt sich das auch im Release-Mode compilieren. Ich dneke aber, dass irgendwo die math.h schon mal includiert wird, bevor ich #define _USE_MATH_DEFINES aufrufe. Wo kann man rausbekommen, in welcher Reihenfolge welche Header eingebunden werden?



  • Projekteigenschaften > C/C++ > Advanced > Show Includes

    Btw, ich verwend sowas:

    namespace math
    {
      template <typename T>
      struct constants;
    
      template <>
      struct constants<float>
      {
        static float  one() { return 1.0f; }
        static float zero() { return 0.0f; }
        static float   pi() { return 3.1415926535897932384626434f; }
        static float    e() { return 2.7182818284590452353602875f; }
      };
    
      template <>
      struct constants<double>
      {
        static double  one() { return 1.0; }
        static double zero() { return 0.0; }
        static double   pi() { return 3.1415926535897932384626434; }
        static double    e() { return 2.7182818284590452353602875; }
      };
    
      template <>
      struct constants<long double>
      {
        static long double  one() { return 1.0; }
        static long double zero() { return 0.0; }
        static long double   pi() { return 3.1415926535897932384626434; }
        static long double    e() { return 2.7182818284590452353602875; }
      };
    }
    
    ...
    bla = math::constants<float>:: pi();
    ...
    

    Hat den Vorteil dass der Typ stimmt.



  • bla = math::constants<float>::zero();
    

    Super Idee.


  • Mod

    Ich habe eben ein Testproject gebaut und genau das gemacht was Du gemacht hast.

    Die entsoprechenden Zeilen einfach ans Ende der stdafx.h gesetzt.
    Ich hatte keinerlei Probleme.



  • Martin Richter schrieb:

    Ich habe eben ein Testproject gebaut und genau das gemacht was Du gemacht hast.

    Die entsoprechenden Zeilen einfach ans Ende der stdafx.h gesetzt.
    Ich hatte keinerlei Probleme.

    So, nach einer Woche Urlaub kann ich mich jetzt wieder an die Problemlösung machen.
    Was hast du denn genau gemacht? Wie gesagt tritt mein Problem nur im Release-Mode auf. Das #define in die stdafx.h zu legen war ja meine erste Idee. Jetzt hab ich mir mal die Include-Reihenfolge anzeigen lassen. Die math.h wird schon relativ zeitig durch irgendwas anderes eingebunden. Ich muss jetzt erst mal rausfinden, welche Unterschiede in der Reihenfolge zwischen Release und Debug bestehen.



  • Schreib doch das #define _USE_MATH_DEFINES vor dem ersten #include (Als erste Nichtkommentarzeile)



  • DirkB schrieb:

    Schreib doch das #define _USE_MATH_DEFINES vor dem ersten #include (Als erste Nichtkommentarzeile)

    Soweit waren wir schon. Es steht definitiv vor dem ersten meiner Includes. Das Problem dabei scheint zu sein, dass das Framework schon vorher einen Include vornimmt (und das auch noch unterschiedlich in Release und Debug).



  • Martin Richter schrieb:

    Ich habe eben ein Testproject gebaut und genau das gemacht was Du gemacht hast.

    Die entsoprechenden Zeilen einfach ans Ende der stdafx.h gesetzt.
    Ich hatte keinerlei Probleme.

    So, ich hab das auch mal in meine stdafx.h reingesetzt. Das Problem besteht noch immer. Jetzt hab ich mir mal die Include-Reihenfolge angeschaut und folgende Unterschiede festgestellt:

    Release:
    Hinweis: Einlesen der Datei:    C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\poppack.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\atlcomcli.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\atlcomtime.h
    Hinweis: Einlesen der Datei:    C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\atlcomtime.inl
    Hinweis: Einlesen der Datei:     C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include\math.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\atlcommem.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\cstringt.inl
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxole.inl
    Hinweis: Einlesen der Datei:  C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxdtctl.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxdtctl.inl
    Hinweis: Einlesen der Datei:  C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxcmn.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxcmn.inl
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxcmn2.inl
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxcmn3.inl
    

    und

    Debug:
    Hinweis: Einlesen der Datei:    C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\include\poppack.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\atlcomcli.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\atlcomtime.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\atlcommem.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\cstringt.inl
    Hinweis: Einlesen der Datei:  C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxdtctl.h
    Hinweis: Einlesen der Datei:  C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxcmn.h
    Hinweis: Einlesen der Datei:   C:\Programme\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\include\afxcmn3.inl
    

    Wieso sehen die Reihenfolgen hier anders aus?

    Trotzdem wird ja bei beiden die stdafx.h als erstes includiert und sieht so bei mir aus:

    // stdafx.h : Includedatei für Standardsystem-Includedateien,
    // oder häufig verwendete, projektspezifische Includedateien,
    // die nur in unregelmäßigen Abständen geändert werden.
    
    #pragma once
    
    #ifndef VC_EXTRALEAN
    #define VC_EXTRALEAN		// Selten verwendete Teile der Windows-Header nicht einbinden
    #endif
    
    // Ändern Sie folgende Definitionen für Plattformen, die älter als die unten angegebenen sind.
    // Unter MSDN finden Sie die neuesten Informationen über die entsprechenden Werte für die unterschiedlichen Plattformen.
    #ifndef WINVER				// Lassen Sie die Verwendung von Features spezifisch für Windows 95 und Windows NT 4 oder später zu.
    #define WINVER 0x0400		// Ändern Sie den entsprechenden Wert, um auf Windows 98 und mindestens Windows 2000 abzuzielen.
    #endif
    
    #ifndef _WIN32_WINNT		// Lassen Sie die Verwendung von Features spezifisch für Windows NT 4 oder später zu.
    #define _WIN32_WINNT 0x0400		// Ändern Sie den entsprechenden Wert, um auf Windows 98 und mindestens Windows 2000 abzuzielen.
    #endif						
    
    #ifndef _WIN32_WINDOWS		// Lassen Sie die Verwendung von Features spezifisch für Windows 98 oder später zu.
    #define _WIN32_WINDOWS 0x0410 // Ändern Sie den entsprechenden Wert, um auf mindestens Windows Me abzuzielen.
    #endif
    
    #ifndef _WIN32_IE			// Lassen Sie die Verwendung von Features spezifisch für IE 4.0 oder später zu.
    #define _WIN32_IE 0x0400	// Ändern Sie den entsprechenden Wert, um auf mindestens IE 5.0 abzuzielen.
    #endif
    
    #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS	// einige CString-Konstruktoren sind explizit
    
    // Deaktiviert das Ausblenden von einigen häufigen und oft ignorierten Warnungen
    #define _AFX_ALL_WARNINGS
    
    #include <afxwin.h>         // MFC-Kern- und -Standardkomponenten
    #include <afxext.h>         // MFC-Erweiterungen
    #include <afxdisp.h>        // MFC-Automatisierungsklassen
    
    #include <afxdtctl.h>		// MFC-Unterstützung für allgemeine Steuerelemente von Internet Explorer 4
    #ifndef _AFX_NO_AFXCMN_SUPPORT
    #include <afxcmn.h>			// MFC-Unterstützung für allgemeine Windows-Steuerelemente
    #endif // _AFX_NO_AFXCMN_SUPPORT
    #include <windows.h>
    #include <afx.h>
    
    #define _USE_MATH_DEFINES
    

    Stimmt hier vielleicht mit den Projekteinstellungen was nicht?



  • dot schrieb:

    Projekteigenschaften > C/C++ > Advanced > Show Includes

    Btw, ich verwend sowas:

    static long double   pi() { return 3.1415926535897932384626434; }
    

    Hat den Vorteil dass der Typ stimmt.

    Warum nicht

    static const long double pi = 3.1415926535897932384626434;
    

    ?


Anmelden zum Antworten