Können Sie einen Kommentar in C #definieren?

Lesezeit: 6 Minuten

Benutzer-Avatar
Ben B.

Ich versuche, ein Debug-System zu erstellen, aber es scheint nicht zu funktionieren.

Was ich erreichen wollte ist ungefähr so:

#ifndef DEBUG
    #define printd //
#else
    #define printd printf
#endif

Gibt es eine Möglichkeit, das zu tun? Ich habe viele Debug-Meldungen und möchte Folgendes nicht tun:

if (DEBUG)
    printf(...)

code

if (DEBUG)
    printf(...)

...

  • Direktes Duplikat von stackoverflow.com/questions/1644868/… und wahrscheinlich auch von anderen.

    – Jonathan Leffler

    23. November 2009 um 19:45 Uhr

  • @JonathanLeffler der Anwendungsfall (Erstellen eines reinen Debug-Druckmakros) ist ein Duplikat von stackoverflow.com/questions/1644868/…, aber die wörtlich gestellte Frage (kann ich einschließen // in einem #define) nicht – und die wörtlich gestellte Frage ist für andere interessant und nützlich. Die Überschneidung ist unglücklich, aber hier gibt es eine eindeutige Frage, die einen Wert hat; es sollte nicht geschlossen werden.

    – Mark Amery

    27. Dezember 2015 um 11:39 Uhr

  • @MarkAmery: Der Titel ist ein ‘XY-Problem’ – Die Lösung für das, was der Benutzer zu erreichen versucht, befindet sich im nominierten Duplikat, aber die Frage fragt nach etwas Tangentialem, das nicht einmal das erreicht, was er will.

    – Jonathan Leffler

    27. Dezember 2015 um 17:24 Uhr

  • @JonathanLeffler Ob Sie den Titel für problematisch halten oder nicht, ich hätte diese Antworten einfach nicht gefunden oder daran gedacht, die Dinge auf eine bestimmte Weise zu tun, wenn ich diesen Titel nicht in den Google-Suchergebnissen angeklickt hätte. Für mich ging es bei den Fragen eher darum, wie man Code ohne Notwendigkeit aus der Produktion entfernen kann #ifdefs überall, und dank der tangentialen Frage von OP fand ich Ideen, die mich auf die richtige Spur brachten. Ich hätte nicht nach einer Frage zu “Debug Printing” gesucht – das ist einfach nicht mein Anwendungsfall!

    – Verschleierung des Benutzernamens

    28. Mai 2018 um 3:35 Uhr


Benutzer-Avatar
AnT steht zu Russland

Nein, das kannst du nicht. Kommentare werden aus dem Code entfernt, bevor die Verarbeitung von Vorverarbeitungsanweisungen beginnt. Aus diesem Grund können Sie keinen Kommentar in ein Makro einfügen.

Außerdem wird nicht garantiert, dass alle Versuche, später einen Kommentar zu “bilden”, indem Sie Makro-Tricks verwenden, funktionieren. Der Compiler muss “verspätete” Kommentare nicht als Kommentare erkennen.

Der beste Weg, das zu implementieren, was Sie wollen, ist die Verwendung von Makros mit variablen Argumenten in C99 (oder vielleicht die Verwendung der Compiler-Erweiterungen).

Benutzer-Avatar
Tim

Ein gängiger Trick ist, dies zu tun:

#ifdef DEBUG
  #define OUTPUT(x) printf x
#else
  #define OUTPUT(x)
#endif

#include <stdio.h>
int main(void)
{   
  OUTPUT(("%s line %i\n", __FILE__, __LINE__));

  return 0;
}

Auf diese Weise haben Sie die ganze Kraft von printf() zur Verfügung, aber Sie müssen die doppelten Klammern in Kauf nehmen, damit das Makro funktioniert.

Der Punkt der doppelten Klammern ist folgender: Sie brauchen einen Satz, um anzuzeigen, dass es sich um einen Makroaufruf handelt, aber Sie können in einem Makro in C89 keine unbestimmte Anzahl von Argumenten haben. Indem die Argumente jedoch in ihre eigenen Klammern gesetzt werden, werden sie als ein einziges Argument interpretiert. Wenn das Makro wann erweitert wird DEBUG definiert ist, ist der Ersetzungstext das Wort printf gefolgt von dem einzelnen Argument, das eigentlich aus mehreren Elementen in Klammern besteht. Die Klammern werden dann als die in der benötigten Klammern interpretiert printf Funktionsaufruf, damit alles funktioniert.

  • außerdem könnten Sie OUTPUT(x…) printf(x) verwenden, um double() zu vermeiden.

    – Brian Postow

    23. November 2009 um 22:25 Uhr

  • @Brian Dies würde nicht funktionieren, wenn Sie eine variable Anzahl von Argumenten wünschen. Einzelheiten siehe Erläuterungstext.

    – Tim

    24. November 2009 um 7:42 Uhr

Benutzer-Avatar
Xeor

С99 Weg:

#ifdef DEBUG
    #define printd(...) printf(__VA_ARGS__)
#else
    #define printd(...)
#endif

Nun, dieser erfordert kein C99, geht aber davon aus, dass der Compiler die Optimierung für die Release-Version aktiviert hat:

#ifdef DEBUG
    #define printd printf
#else
    #define printd if (1) {} else printf
#endif

  • Richtig, aber nicht ganz portabel.

    – Tim Post

    23. November 2009 um 19:04 Uhr

  • Viel besser, aber auch hier deaktiviert die “portable” Version die Gültigkeitsprüfungen der Argumente nicht. Der richtige Weg, dies in einer Nicht-C99-Implementierung zu tun, ist in Tims Antwort angegeben.

    – AnT steht zu Russland

    23. November 2009 um 19:15 Uhr

  • Und das ist seine gute Seite, denke ich. Warum die Gültigkeitsprüfung für Code deaktivieren, der in Debug-Versionen echt sein wird?

    – Xeor

    23. November 2009 um 19:15 Uhr

  • Ganz einfach: weil dieser Code in Release-Versionen möglicherweise ungültig ist. Es ist nichts Falsches daran, dass der Debug-Code in der Version ungültig ist. Außerdem ist es meistens so.

    – AnT steht zu Russland

    23. November 2009 um 19:19 Uhr

  • @AndreyT: Obwohl diese Frage ziemlich alt ist und bereits beantwortet wurde, bin ich von Ihrem Kommentar fasziniert. Können Sie ein Beispiel angeben oder darauf verweisen, in dem der Debug-Code in Release-Versionen möglicherweise ungültig ist? Vielen Dank.

    – Carla Alvarez

    21. Januar 2010 um 14:21 Uhr

Benutzer-Avatar
Igor Barbar

Bei einigen Compilern (einschließlich MS VS2010) funktioniert dies,

#define CMT / ## /

aber keine Stipendiaten für alle Compiler.

Sie können Ihren gesamten Debug-Aufruf in eine Funktion packen und ihn aufrufen lassen printf_debug und lege die DEBUG innerhalb dieser Funktion. Der Compiler optimiert die leere Funktion.

  • Danke, endlich Vernunft … außer dass es hauptsächlich die Arbeit des Präprozessors ist.

    – Tim Post

    23. November 2009 um 19:01 Uhr

  • In diesem Fall könnten Sie einfach Ihre Funktion printd aufrufen

    – Tadman

    23. November 2009 um 19:02 Uhr

  • Dies deaktiviert nicht die Auswertung von Argumenten und deaktiviert nicht die Anforderung, dass die Argumente gültig sind (wie beispielsweise deklariert). Mit anderen Worten, es tut nicht, was angefordert wurde.

    – AnT steht zu Russland

    23. November 2009 um 19:10 Uhr

  • @AndreyT, wenn irgendeine Art von Linkzeitoptimierung durchgeführt wird, fügt der Compiler leere Funktionen ein und entfernt toten Code zum Auswerten von Argumenten.

    – Jay Conrod

    23. November 2009 um 19:11 Uhr

  • Das Problem ist, dass es einfach nicht kompiliert wird, wenn die Argumente im Release-Kontext nicht gültig sind. Es kommt nicht zu “Optimierung”.

    – AnT steht zu Russland

    23. November 2009 um 19:21 Uhr

Der Standardweg ist die Verwendung

#ifndef DEBUG
    #define printd(fmt, ...)  do { } while(0)
#else
    #define printd(fmt, ...) printf(fmt, __VA_ARGS__)
#endif

Wenn Sie also am Ende ein Semikolon hinzufügen, macht es, was Sie wollen. Da es keine Operation gibt, kompiliert der Compiler das “do…while”

  • Danke, endlich Vernunft … außer dass es hauptsächlich die Arbeit des Präprozessors ist.

    – Tim Post

    23. November 2009 um 19:01 Uhr

  • In diesem Fall könnten Sie einfach Ihre Funktion printd aufrufen

    – Tadman

    23. November 2009 um 19:02 Uhr

  • Dies deaktiviert nicht die Auswertung von Argumenten und deaktiviert nicht die Anforderung, dass die Argumente gültig sind (wie beispielsweise deklariert). Mit anderen Worten, es tut nicht, was angefordert wurde.

    – AnT steht zu Russland

    23. November 2009 um 19:10 Uhr

  • @AndreyT, wenn irgendeine Art von Linkzeitoptimierung durchgeführt wird, fügt der Compiler leere Funktionen ein und entfernt toten Code zum Auswerten von Argumenten.

    – Jay Conrod

    23. November 2009 um 19:11 Uhr

  • Das Problem ist, dass es einfach nicht kompiliert wird, wenn die Argumente im Release-Kontext nicht gültig sind. Es kommt nicht zu “Optimierung”.

    – AnT steht zu Russland

    23. November 2009 um 19:21 Uhr

Ungetestet: Bearbeiten: Getestet, benutze es jetzt selbst 🙂

#define DEBUG 1
#define printd(fmt,...) if(DEBUG)printf(fmt, __VA_ARGS__)

erfordert, dass Sie nicht nur definieren DEBUG aber geben Sie ihm auch einen Wert ungleich Null.

Anhang: Funktioniert auch gut mit std::cout

1381760cookie-checkKönnen Sie einen Kommentar in C #definieren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy