Funktionen, die nur in Debug funktionieren - zB assert-Makro



  • Hallo,
    das assert-Makro ist ja ganz praktisch. Nun bräuchte ich euch noch einige andere Funktionen, die aber nur in Debug kompiliert werden.
    Momentan löse ich das so, sehr umständlich:

    #ifdef _DEBUG
    meineFunktion(zuKontrollierenderWert);
    #endif
    

    Und das gleiche dann noch bei der Funktionsdefinition...
    Kann man das nicht expliziet angeben?
    Habe mir schon die Header-datei des assert-Makro angeschaut, bin aber leider nicht draus schlau geworden... 😕



  • Das geht zum Beispiel so:

    void meineEchteFunktion(int wert) { ... }
    
    #ifdef _DEBUG
        #define meineFunktion(wert) meineEchteFunktion(wert)
    #else
        #define meineFunktion(wert)
    #endif
    


  • #include <assert.h>
    
    int main() {
    
        int *pointer = new int;
    
        // ...
    
        pointer = 0;
    
        // ...
    
        assert(pointer);
        *pointer = 23;
    
        return 0;
    
    }
    

    Bei dem Beispiel würde die Zeile assert(pointer) nur im Debug-Modus kompiliert.
    In dem Falle würde mir eine Fehlermeldung ausgegeben.

    Ich möchte nicht meine Funktion mit einer anderen ersetzen.



  • Das geht zum Beispiel so:

    #ifdef _DEBUG
        void meineDebugFunktion(int wert);
    #else
        void meineReleaseFunktion(int wert);
    #endif
    
    #ifdef _DEBUG
        #define meineFunktion(wert) meineDebugFunktion(wert)
    #else
        #define meineFunktion(wert) meineReleaseFunktion(wert)
    #endif
    


  • Ich glaube ihr versteht nicht ganz. Ihr beschreibt es so, als hätte ich eine Funktion, die für Debug und eine für Release.
    Ich habe nur eine Funktion, die im Debug-Modus überprüfen soll, ob ein Zeiger noch gültig ist. Aber nicht in der Release.

    Das ist der quellcode des assert-Makro:

    /***
    *assert.h - define the assert macro
    *
    *       Copyright (c) Microsoft Corporation. All rights reserved.
    *
    *Purpose:
    *       Defines the assert(exp) macro.
    *       [ANSI/System V]
    *
    *       [Public]
    *
    ****/
    
    #include <crtdefs.h>
    
    #undef  assert
    
    #ifdef  NDEBUG
    
    #define assert(_Expression)     ((void)0)
    
    #else
    
    #ifdef  __cplusplus
    extern "C" {
    #endif
    
    _CRTIMP void __cdecl _wassert(_In_z_ const wchar_t * _Message, _In_z_ const wchar_t *_File, _In_ unsigned _Line);
    
    #ifdef  __cplusplus
    }
    #endif
    
    #define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
    
    #endif  /* NDEBUG */
    

    Man könnte ja auch:

    #ifdef _DEBUG
    Funktion
    #endif
    

    schreiben.

    Aber das geht ja, wie man sieht einfacher.

    \\EDIT:

    Ok bin selber draufgekommen, trozdem danke.

    Meine Lösung:

    #ifdef _DEBUG
    #define controlPointer(x) {if(!x) {exit(0)}}
    #endif
    

    Und nochmal im Beispiel:

    #ifdef _DEBUG
    #define controlPointer(x) {if(!x) {std::cout << "ERROR!\n";}}
    #endif
    
    #include <iostream>
    
    int main() { 
    
        int *pointer = new int; 
    
        // ... 
    
        pointer = 0; 
    
        // ... 
    
        controlPointer(pointer); 
        *pointer = 23; 
    
        return 0; 
    
    }
    

    Hier würde dann die Meldung kommen, da der Zeiger bereit auf 0 gesetzt wurde.
    Diese Kontrolle passiert aber nur in der Debug-Version, habe also keine Performance Einbuße in der Release-Version. 😃



  • PAiNTiNG schrieb:

    Diese Kontrolle passiert aber nur in der Debug-Version, habe also keine Performance Einbuße in der Release-Version. 😃

    Und jetzt bitte mal release kompilieren. Schau dir dein Beispiel an und dann das von Nukularfüsiker. Außerdem hast du jetzt deinen Code in ein Macro gepackt, was bei so kurzen Sachen vllt. gerade noch vertretbar ist (ich würdes trotzdem meiden), aber lass das dann mal wachsen und gedeihen und du sehnst dich nach einer ordentlichen Funktion 😉



  • Also erstmal heisst "control" steuern und nicht überprüfen. Überprüfen wäre "check".

    Davon abgesehen:

    #ifdef _DEBUG
    #define checkPointer(x) assert(static_cast<void const volatile*>(x) != 0)
    #else
    #define checkPointer(x) ((void)0)
    #endif
    

    Und Makros mit Control-Flow-Konstrukten und/oder Scopes schreibt man üblicherweise so:

    #define checkPointer(x) do { meinCode(); } while(0)
    // oder
    #define checkPointer2(x) if (0); else { meinCode(); }
    


  • eine loesung mittels templates koennte so aussehen:

    #ifdef _DEBUG
       static const int only4debug = 0;
    #else
       static const int only4debug = 1;
    #endif
    
    template<int val>
    void check_pointer(const void* p)
    {
       p; /* nur damit sich der compiler nicht aufregt */
       return; 
    }
    
    template<>
    void check_pointer<0>(const void *p)
    {
       if(p == 0)
          exit(0);
    }
    
    check_pointer<only4debug>(ptr);
    

    Meep Meep


Anmelden zum Antworten