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
-
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
undinline
gemeinsam. Und zwar weil ichinline
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
undinline
gemeinsam. Und zwar weil ichinline
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, dennUnused(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).