Logfile ohne Overhead



  • wow, danke für die vielen sehr interessanten Beiträge... Ich glaub ich schau mir erstmal meinen Compiler an und werd dann sehen was geht und was nicht 😉

    Thx!



  • Mal noch eine Frage:
    Macht es mehr Sinn, das Logfile einmal zu öffnen und erst wieder bei Programmende zu schließen oder bei jedem Zugriff zu öffnen/schließen?

    Das Ganze soll ja auch bei Programmausfällen funktionieren, ist das problematisch, wenn evtl. das close entfällt (wenn man nur einmal öffnet und das Programm vor dem Schließen crasht)?
    Performance-technisch wäre ja einmal öffnen schneller...



  • Grundsätzlich sollte einmal öffnen vollkommen ausreichen. Bei einem Absturz sollte das Betriebssystem zusehen, dass die Resourcen wieder freigegeben werden. Letztendlich kann man das mit Exception aber in den meisten Fällen dank der Destruktoren sogar selber erledigen.



  • CSpille schrieb:

    Wieso eigentlich die Verwendung von Makros im Code?

    Ich würde etwa sowas machen:

    #ifdef DEBUG
    const bool DEBUG_MODE  = 1;
    #elsif
    const bool DEBUG_MODE  = 0;
    #endif
    

    Du solltest aber niemals nicht auf gar keinen Fall eine Konstante in GROSSBUCHSTABEN schreiben, da dies per Konvention den Makros vorbehalten ist. Gerade mit deinem zweiten Beispiel

    const int DEBUG = 1;
    

    könntest du Probleme bekommen.

    Lars



  • DOCH AUF JEDEN FALL GROSS SCHREIBEN. DER CODE GEHÖRT EH IN EINEN NAMESPACE:



  • _ schrieb:

    DOCH AUF JEDEN FALL GROSS SCHREIBEN. DER CODE GEHÖRT EH IN EINEN NAMESPACE:

    Soso, und das ändert was an dem Problem?

    Lars



  • manni66 schrieb:

    Du solltest aber niemals nicht auf gar keinen Fall eine Konstante in GROSSBUCHSTABEN schreiben, da dies per Konvention den Makros vorbehalten ist. Gerade mit deinem zweiten Beispiel

    const int DEBUG = 1;
    

    könntest du Probleme bekommen.

    Danke für den Hinweis, jedoch bin ich jetzt etwas überrascht, denn wenn ich
    mir so (Vorschläge für) Coding-Conventions ankucke, dann sieht man das
    häufiger:
    http://geosoft.no/development/cppstyle.html

    Das ist nur ein Beispiel.

    Generell dachte ich, dass der Compiler seine MACROS mit '_'
    anfängt.

    Deswegen habe ich bisher nur darauf geachtet, dass ich sowas nicht mache.
    Ausnahme sind include guards.

    Die haben bei mir folgende Form:

    #ifndef _MY_CLASS_H_
    #define _MY_CLASS_H_
    #endif
    

    Warum eigentlich? 🤡

    Im gerade eingefügten Link beginnen (und enden) sie nicht mit '_' 🙄



  • CSpille schrieb:

    Ausnahme sind include guards.
    #ifndef _MY_CLASS_H_

    Ja, weil Du oder dein Buchautor in den vom Compilerbauer mitgelieferten Includefiles mal gestöbert haben und die machen es so. Also macht man es selber nach. Ganz falscher Fehler das.



  • volkard schrieb:

    CSpille schrieb:

    Ausnahme sind include guards.
    #ifndef _MY_CLASS_H_

    Ja, weil Du oder dein Buchautor in den vom Compilerbauer mitgelieferten Includefiles mal gestöbert haben und die machen es so. Also macht man es selber nach. Ganz falscher Fehler das.

    Genau das, was ich befürchtet habe...
    Deine include guards heißen;

    #ifndef MY_CLASS_H
    

    ?

    Bestehen Konstanten bei dir aus Großbuchstaben?



  • CSpille schrieb:

    Bestehen Konstanten bei dir aus Großbuchstaben?

    Wenn sie sich anfühlen wie Makros, also mal PI oder so, dann meistens ja.
    Aber immer mehr Konstanten wandern mit static const in Klassen rein und da schreibe ich sie wie normale Variablen.



  • CSpille schrieb:

    Generell dachte ich, dass der Compiler seine MACROS mit '_'
    anfängt.

    Das Problem sind ja nicht nur die Makros, die vom Compiler kommen. Jeder kann in einem Header etwas definieren. Gerade DEBUG wird fast immer auf der Kommandozeile benutzt, wenn im Debugmodus übersetzt wird. Release wird dann häufig mit NDEBUG übersetzt (das assert verlangt das seit eh und je so).

    In Qt3 wird z.B. "signals" (entgegen der Konvention in Kleinbuchstaben) definiert. Jeder, der schon mal boost signals benutzt hat, wünscht den Trollen vermutlich die Pest an den Hals 😉

    Auch Adobe und Apple bekleckern sich da nicht gerade mit Ruhm.

    Würden sich alle an die Konvention halten, gäbe es viel seltener Probleme.

    Lars



  • volkard schrieb:

    Wenn sie sich anfühlen wie Makros, also mal PI oder so, dann meistens ja.

    M_PI ist in math.h bzw cmath definiert, PI brauch man also nicht 😉

    Lars



  • manni66 schrieb:

    Gerade DEBUG wird fast immer auf der Kommandozeile benutzt, wenn im Debugmodus übersetzt wird. Release wird dann häufig mit NDEBUG übersetzt (das assert verlangt das seit eh und je so).

    Okay... DEBUG war vielleicht kein sooo gutes Beispiel 🙄

    Du denkst dabei an Folgendes, oder?

    #include<iostream>
    
    const int DEBUG = 1;
    
    int main() {
            if(DEBUG)
                    std::cout << "DEBUG" << std::endl;
            return 0;
    }
    
    g++ main.cpp -DDEBUG -o test
    

    wobei DEBUG von manchen Compilern automatisch definiert wird.

    main.cpp:3: error: expected unqualified-id before numeric constant
    


  • ...



  • CSpille schrieb:

    Dieses Argument hat mich inzwischen überzeugt, so dass ich
    zukünftig sowas vorziehen werde:

    #include<iostream>
    
    inline void debug(const std::string & debugMessage){
    #ifdef DEBUG
            std::cout << debugMessage << std::endl;
    #endif
    }
    
    int main() {
            debug("running programm");
            return 0;
    }
    

    Indem ich die Debug-Funktion in einem separaten Header definiere, kann ich
    meinen Code ebenfalls frei von Macros halten...

    Schade.

    #include<iostream>
    
    inline void debug(const std::string & debugMessage){
    #ifdef DEBUG
            std::cout << debugMessage << std::endl;
    #endif
    }
    
    int main() {
            debug(getLocalMachineDesription());
            return 0;
    }
    

    Braucht 20 Sekunden, was halt im Debug-Code notwenig ist und bezahlt wird. Aber im Release-Code? 🤡



  • liefert dir genau genommen noch immer eine warning (im release-mode - unreference variable)

    template<typename T>
    void debug_msg(const T& to_write, std::ostream& output = std::cout);
    
    #ifdef NDEBUG
    # include "debug_release.inl"
    #else
    # include "debug_debug.inl"
    #endif
    
    /*debug_debug.inl*/
    template<typename T>
    void debug_msg(const T& to_write, std::ostream& output)
    {
      output << to_write;
    }
    
    /*debug_release.inl*/
    template<typename T>
    void debug_msg(const T& /*to_write*/, std::ostream& /*output*/)
    {}
    

    so würde ich es vermutlich handhaben...

    bb

    @volkard: sollte wegoptimiert werden ;o)
    Je nach anwendungsgebiet kann man (worauf du sicherlich hinauswolltest.. ^^) aber auch komplett Makros nehmen - hat den Vorteil, dass man sich Variablennamen etc alles auf einmal einblenden lassen kann...



  • unskilled schrieb:

    @volkard: sollte wegoptimiert werden ;o)

    Ein Funktionsaufruf mit etlichen Syscalls drinne wird eher nicht wegoptimiert. Da würde ich mir keine Hoffnungen machen.

    Je nach anwendungsgebiet kann man (worauf du sicherlich hinauswolltest.. ^^) aber auch komplett Makros nehmen - hat den Vorteil, dass man sich Variablennamen etc alles auf einmal einblenden lassen kann...

    Oder auch mal #ifdef DEBUG im eigenen Code auftauchen lassen. Ist zwar wirklich nicht schön, aber es ist so einfach, daß sogar der Chef es versteht.



  • ...



  • CSpille schrieb:

    Da ist doch kein einziger Syscall drin...
    Die sind nach Bearbeitung des Preprozessors doch schon raus, oder?

    debug(getLocalMachineDesription());
    

    Doch in getLocalMachineDesription()! Und die Funktion wird ausgewertet, um den string zu erzeugen, der der debug() übergeben wird. Daß die debug() dann den string ignoriert, kann nicht dafür sorgen, daß die getLocalMachineDesription() nicht aufgerufen wird.
    Wegen einiger Syscalls, um eine Beschreibung der lokalen Maschine auszulesen und zusammnzubasteln, ist das Ding für den Compiler so seiteneffektbehaftet wie printf und wird wie auch printf-Aufrufe nicht nur deswegen wegoptimiert, weil man den Return-Wert nicht in weitere Berechnungen oder Ausgaben einfließen läßt.



  • ...


Anmelden zum Antworten