Mit präprozessor befehlen Auskommentieren
-
nichtconnected schrieb:
Muss man sed nicht extra installieren?
Es ist kein Teil eines C++-Compilers. Wenn es absolut unabhängig portierbar sein muss, kannst du ja selber ein kleines Ersetzenprogramm mitliefern (oder eine Opensource-Implementierung von sed), welches als allererstes übersetzt wird und dann im folgenden vor alle weiteren Compilierungsvorgänge geschaltet wird.
-
Was ist mit #ifdef und #ifndef?
SeppJ schrieb:
eine Opensource-Implementierung von sed
Was sonst?
-
Das ist nicht genau das selbe, aber womöglich tut's schon
#define Extra if(false)
-
@seldon
Es reicht nicht für mich. Ich will die ganze Zeilen, die mit Extra anfangen auskommentieren.@SeppJ
Danke, aber ich muss es leider mit präpozessor befehlen machen.Ich bin langsam überzeug, dass es nicht möglich ist.
-
Wenn es sich bei der Anwendung nur um eine Art
DEBUG_ONLY
handelt, kann man auch ein normales Makro nehmen:#ifdef DEBUG #define DEBUG_ONLY(...) __VA_ARGS__ #else #define DEBUG_ONLY(...) #endif
Dann ist eben
DEBUG_ONLY cout << "Pos:" << get_pos(x, y); --> DEBUG_ONLY(cout << "Pos:" << get_pos(x, y));
Das finde ich noch annehmbar, in Anbetracht der Tatsache, dass es keine wirkliche Alternative gibt.
-
Ich habe nicht verstanden. Kannst du erkäeren was genau dieser Code macht?
-
nichtconnected schrieb:
Ich habe nicht verstanden. Kannst du erkäeren was genau dieser Code macht?
Das angegebene Statement wird nur im Debug-Build ausgeführt.
-
seldon schrieb:
Das ist nicht genau das selbe, aber womöglich tut's schon
#define Extra if(false)
Das kann nicht funktionieren, da dann "offizielle Befehle" folgen müssen - Kommentare sind da völlig unmöglich.
-
Hacker schrieb:
Das kann nicht funktionieren, da dann "offizielle Befehle" folgen müssen - Kommentare sind da völlig unmöglich.
Wenn man Kommentare hat, schreibt man auch nicht
Extra
, sondern//
an den Zeilenanfang. Es geht hier schon um bedingte Kompilierung. Aber dafür istif(false)
auch nicht ganz das Wahre, weil der Code trotzdem kompiliert wird.
-
Sorry wenn ich doof frage, aber welchen Sinn soll das haben? Und warum nicht:
#define EXTRA #ifdef EXTRA foobar(); #endif
??
Bei Bedarf kannst das #define EXTRA ja auskommentieren.
-
Ich hätte das auch einmal gerne gehabt: Bei der GUI-Programmierung hatte ich mir ein Edit-Feld in einem Debug-Fenster angelegt, das bei jedem Aufruf von
dbgout << "Fehler (" << err << ")\n";
, falls nicht sichtbar, angezeigt und der Text dem Editfeld zugefügt wird (ein Editfeld deswegen, weil ich darin im Ggs. zu einer Konsole "beliebig" viel Text unterbringen kann).
Natürlich möchte man das nur in der Debug-Version haben. Und jedes mal nen #ifdef/endif da herum zu haben, ist auch nicht so toll.Ich habe mir dann damit geholfen, in den Release-Versionen die Operatoren einer anderen Klasse aufzurufen, die diese Eingaben sofort verwirft.
In den Release-Versionen wird somit auch kein zusätzlicher Code ausgeführt - es wäre aber dennoch einfacher gewesen, den Präprozessor zum Auskommentieren zu überreden.
-
yahendrik schrieb:
Ich hätte das auch einmal gerne gehabt: Bei der GUI-Programmierung hatte ich mir ein Edit-Feld in einem Debug-Fenster angelegt, das bei jedem Aufruf von
dbgout << "Fehler (" << err << ")\n";
, falls nicht sichtbar, angezeigt und der Text dem Editfeld zugefügt wird (ein Editfeld deswegen, weil ich darin im Ggs. zu einer Konsole "beliebig" viel Text unterbringen kann).
Natürlich möchte man das nur in der Debug-Version haben. Und jedes mal nen #ifdef/endif da herum zu haben, ist auch nicht so toll.Ich habe mir dann damit geholfen, in den Release-Versionen die Operatoren einer anderen Klasse aufzurufen, die diese Eingaben sofort verwirft.
In den Release-Versionen wird somit auch kein zusätzlicher Code ausgeführt - es wäre aber dennoch einfacher gewesen, den Präprozessor zum Auskommentieren zu überreden.In so einem Fall kann man doch eine globale Funktion machen:
void dbgout(const std::string& description) { #ifdef _DEBUG std::cerr << "Fehler: " << description << std::endl; #endif }
Ich behaupte mal, dass im Release Modus der komplette Call auf die Funktion wegoptimiert wird.
-
Scorcher24 schrieb:
In so einem Fall kann man doch eine globale Funktion machen
... und nur einen String übergeben.
Nein, eine Klasse mit überladenen Streamoperatoren ist dafür ideal.
-
Nexus schrieb:
Scorcher24 schrieb:
In so einem Fall kann man doch eine globale Funktion machen
... und nur einen String übergeben.
Nein, eine Klasse mit überladenen Streamoperatoren ist dafür ideal.
Okay, für die pendanten:
void dbgout(const std::string& description, int line, const std::string& file) { #ifdef _DEBUG std::cerr << "Fehler in Datei: " << file << " in Zeile " << line << ". Meldung: " << description << std::endl; #endif }
-
Scorcher24 schrieb:
In so einem Fall kann man doch eine globale Funktion machen:
void dbgout(const std::string& description) { #ifdef _DEBUG std::cerr << "Fehler: " << description << std::endl; #endif }
Ich behaupte mal, dass im Release Modus der komplette Call auf die Funktion wegoptimiert wird.
Aber nicht die Bereitstellung des Strings.
dbgout(std::string("Fehler in ")+__FILE__+":"+toString(__LINE__)+"."+getCurrentUserName()+" "+toString(getCurrentTime())+" "+toString(getPingDelay()));
Solange im Release-Code getPingDelay() ausgeführt werden muß, bin ich dagegen.
Entsprechend bin ich auch gegen einen einfachen Stream.
-
In so einem Fall eignet sich mein DEBUG_ONLY-Makro von Seite 2.
-
Michael E. schrieb:
Edit: Ich sollte meine eigenen Google-Links zuerst vollständig lesen und dann erst posten.
Was spricht denn jetzt eigentlich hier gegen?
-
fdfdg schrieb:
Michael E. schrieb:
Edit: Ich sollte meine eigenen Google-Links zuerst vollständig lesen und dann erst posten.
Was spricht denn jetzt eigentlich hier gegen?
Es funktioniert nicht bei einem standardkonformen Compiler.
-
fdfdg schrieb:
Michael E. schrieb:
Edit: Ich sollte meine eigenen Google-Links zuerst vollständig lesen und dann erst posten.
Was spricht denn jetzt eigentlich hier gegen?
Lies mal den italic geschriebenen Kommentar.
-
Scorcher24 schrieb:
void dbgout(const std::string& description, int line, const std::string& file) { #ifdef _DEBUG std::cerr << "Fehler in Datei: " << file << " in Zeile " << line << ". Meldung: " << description << std::endl; #endif }
Ja, sicher. Und wenn wir dann zusätzlich noch irgendeinen Index oder sonst was ausgeben wollen, schreiben wir einfach eine weitere Überladung mit einem neuen Parameter
std::size_t index
. Oder noch besser, wir brauchen beim Aufruf jedes Mal einenstd::stringstream
, um sich alles zusammenzuflicken und von daraus den String mitstr()
zu kopieren und andbgout
zu übergeben.Sofern man nicht immer nur fertige Strings übergibt, ist eine Stream-Klasse viel flexibler. Und wenn man immer fertige Strings übergibt, kann der Parameter auch
const char*
sein...Das einzige, was vielleicht halbwegs Sinn machen würde, wäre Folgendes. Aber auch hier haben wir wieder eine Klasse mit Streamsemantik.
class Streamer { public: template <typename T> Streamer& operator<< (const T& value); operator std::string() const; private: std::stringstream stream; }; #define DBGOUT(string) dbgout(string, __LINE__, __FILE__) void dbgout(const std::string& str, int line, const char* file); DBGOUT( Streamer() << "Fehler bei Index " << index );