Warnings vermeiden



  • Hallo,

    Ich habe Funktionen mit Argumenten, die im Debug-Modus verwendet werden, im
    Release-Modus aber nicht. Folglich bekommt man beim Compilieren mit -DNDEBUG
    jede Menge Warnings serviert. Ein Beispiel ist folgendes:

    void info(string who,string what)
    {
    #ifndef NDEBUG
    	cout<<endl;
    	if(who.length()>0) cout<<magentaString("      "+who+", INFO: "+what)<<endl;
    		else cout<<("      "+who+"INFO: "+what)<<endl;
    	cout<<endl;
    #endif
    }
    
    tools.cpp:67: warning: unused parameter ‘who’
    tools.cpp:67: warning: unused parameter ‘what’
    

    Klar, man kann die Warnings des Compilers selektiv ausschalten, aber das soll
    nicht gemacht werden, sondern es sollte gezielt im Code gesagt werden 'Das
    hier ist kein Problem'. Gibts dafür ein #pragma oder einen anderen Trick?
    Verwendet wird GCC.



  • Sollte eigentlich reichen:

    template <typename T>
    inline void Unused(const T&)
    {
    }
    
    void info(std::string who, std::string what)
    {
        Unused(who);
        Unused(what);
    
        // ...
    }
    


  • Nexus schrieb:

    Sollte eigentlich reichen:

    template <typename T>
    inline void Unused(const T&)
    {
    }
    
    void info(std::string who, std::string what)
    {
        Unused(who);
        Unused(what);
    
        // ...
    }
    

    Gute Idee, danke. Aber weshalb "template" und "inline"? Templates sind
    doch immer inline.

    lg


  • Mod

    assertx schrieb:

    Gute Idee, danke. Aber weshalb "template" und "inline"? Templates sind
    doch immer inline.

    Nein. Für Templates gelten bloß ähnliche Regeln wie für inline, aber die besondere Bedeutung als Hinweisgeber für Compileroptimierungen ist nicht da.



  • Templates sind nicht immer inline, aber sie müssen immer vollständig definiert werden. Das inline ist im Prinzip unnötig, aber dadurch sollte der Compiler noch weniger auf die Idee kommen, die Funktion aufzurufen. Wobei moderne Compiler das sowieso komplett wegoptimieren sollten.

    Ich verwende sonst eigentlich nie template und inline gemeinsam. Und zwar weil ich inline so gut wie nie zur Optimierung verwende, sondern nur um Funktionen im Header definieren zu können.



  • Nexus schrieb:

    Templates sind nicht immer inline, aber sie müssen immer vollständig definiert werden. Das inline ist im Prinzip unnötig, aber dadurch sollte der Compiler noch weniger auf die Idee kommen, die Funktion aufzurufen. Wobei moderne Compiler das sowieso komplett wegoptimieren sollten.

    Ich verwende sonst eigentlich nie template und inline gemeinsam. Und zwar weil ich inline so gut wie nie zur Optimierung verwende, sondern nur um Funktionen im Header definieren zu können.

    Ah, ok. Danke.



  • Noch etwas zum Thema Warnings:

    // Faster and more intuitive than num=(num+1)%3...
    inline int incIndexBy1(const unsigned num) 
    {
    	assert(num<3);
    	int incArray[]={1,2,0};
    	return incArray[num];
    }
    
    tools.h:99: warning: array subscript is above array bounds
    

    Im Release-Modus kommt das Warning, was eigenartig ist, da der Compiler gar
    nicht wissen kann, wie groß num ist. Gibt es einen Weg, ihm ohne ein 'if(..)'
    mitzuteilen, daß num<3 ist?



  • Man kann Warnings auch mit #pragmas lokal deaktivieren. Im Visual Studio geht das mit #pragma warning(push) , #pragma warning(disable: xxx) und [c]#pragma warning(pop) soweit ich mich erinnere. Beim GCC werden die vermutlich ähnlich heißen.
    Trotzdem seltsam, dass die Warnung kommt. Sicher, dass nicht irgendwo die Funktion mit einem konstanten Wert größer als 3 aufgerufen wird?



  • ipsec schrieb:

    Man kann Warnings auch mit #pragmas lokal deaktivieren. Im Visual Studio geht das mit #pragma warning(push) , #pragma warning(disable: xxx) und [c]#pragma warning(pop) soweit ich mich erinnere. Beim GCC werden die vermutlich ähnlich heißen.
    Trotzdem seltsam, dass die Warnung kommt. Sicher, dass nicht irgendwo die Funktion mit einem konstanten Wert größer als 3 aufgerufen wird?

    Die Funktion wird von vielen Stellen aus aufgerufen. Manchmal gibt es dabei
    Schleifen mit

    // Vereinfachtes Beispiel:
    for(unsigned num=0;num<10;++num)
    {
    ..bla
    unsigned idx=incIndexBy1(num)
    }
    

    In diesen Fällen verhindern Bedingungen innerhalb von "..bla", daß die Funktion
    aufgerufen wird. Da die zur Compilezeit noch unbekannt sind, warnt der Compiler
    erst mal.



  • ich habe irgendwie im hinterkopf rumspu(c)ken dass man so eine warung auch mit einem vorgestelltem void umgehen kann - dann spart man sich das template. Also

    void myFunc(int val)
    { 
        #ifdef DEBUG 
            val += 2;
            /* usw */ 
        #else
            (void) val; 
        #endif
    }
    

    Hack oder ok? Schein ein C Style cast nach void zu sein?



  • Das ist schon okay, allerdings ist das #ifdef #else #endif jedes Mal etwas unschön. Die Fallunterscheidung ist eigentlich gar nicht nötig. Und ich würde das wenn schon in ein Makro verpacken, denn Unused(x) ist einfach klarer als (void)x .

    Aber es könnte sein, dass gewisse Compiler dies nicht als Benutzung ansehen und die Warnung weiter ausgeben, oder sogar eine neue Warnung erzeugen ("Ausdruck hat keine Effekte" oder so).


Log in to reply