Sind leere Makrodefinitionen in C erlaubt? Wie verhalten sie sich?

Lesezeit: 3 Minuten

Nehmen wir die “leere” Makrodefinition an

#define FOO

Ist es gültiger Standard C? Wenn ja, was ist FOO nach dieser Definition?

  • Es ist eine leere Zeichenfolge, und ja, es ist akzeptabel.

    – nhahtdh

    15. Dezember 2012 um 12:30 Uhr

  • Nur um darauf hinzuweisen, hier ist eine weitere Frage, die eine interessante Verwendung leerer Definitionen beinhaltet.

    – Sidyl

    15. Dezember 2012 um 12:40 Uhr

Benutzeravatar von Zeta
Zeta

Es ist einfach ein Makro, das zu nichts erweitert wird. Nun, da das Makro definiert wurde, können Sie es überprüfen #if defined (oder #ifdef), ob es definiert wurde.

#define FOO

int main(){
    FOO FOO FOO
    printf("Hello world");
}

wird erweitern

int main(){

    printf("Hello world");
}

Es gibt bestimmte Situationen, in denen dies sehr praktisch ist, zum Beispiel zusätzliche Debug-Informationen, die Sie nicht in Ihrer Release-Version anzeigen möchten:

/* Defined only during debug compilations: */
#define CONFIG_USE_DEBUG_MESSAGES

#ifdef CONFIG_USE_DEBUG_MESSAGES
#define DEBUG_MSG(x) print(x)
#else
#define DEBUG_MSG(x) do {} while(0)
#endif

int main(){
    DEBUG_MSG("Entering main");
    /* ... */
}

Da das Makro CONFIG_USE_DEBUG_MESSAGES Wurde definiert, DEBUG_MSG(x) wird erweitern print(x) und du wirst bekommen Entering main. Wenn Sie die entfernen #define, DEBUG_MSG(x) erweitert sich zu einem leeren dowhile Schleife und Sie werden die Nachricht nicht sehen.

  • Dies ist sehr riskant, da es die Kompilierung beschädigen kann, insbesondere. wenn Sie Aussagen wie haben if (x) DEBUG_MSG("test"); else DEBUG_MSG("test");. Ich ziehe es vor, mein leeres Makro mit einer wirkungslosen Anweisung wie zu deklarieren #define DEBUG_MSG(x) do {} while(0)

    – Eli

    24. Februar 2017 um 8:55 Uhr


  • @Ely Warum sollte das kaputt gehen? Wenn DEBUG_MSG wurde definiert als #defined DEBUG_MSG(x) dann else DEBUG_MSG("test") wird einfach else ; was gilt, weil ; ist die “leere Aussage”.

    – Pharap

    5. Mai 2018 um 23:43 Uhr

  • Ich mache manchmal so etwas: #define NOTHING Dann sowas wie int NOTHING main()

    Benutzer12211554

    17. Juli 2019 um 21:58 Uhr

  • @Ely Warum sollte das kaputt gehen? Warum nicht einfach {}?

    – Endolith

    27. August 2021 um 18:57 Uhr

  • Aber in der realen Welt haben Protokollfunktionen verschiedene Parameter DEBUG_MSG("message %s %s %s", parameters, and, more);. Es ist immer noch kompatibel mit einer solchen Syntax, oder müssen wir aufpassen oder die Parameter, die mit der Funktion im Release-Modus gelöscht werden müssen?

    – Sandburg

    18. Mai um 8:17 Uhr


Benutzeravatar von md5
md5

Ja, der Standard erlaubt eine leere Definition.

C11 (n1570), § 6.10 Vorverarbeitungsrichtlinien

control-line:
   # define identifier replacement-list new-line
   # define identifier lparen identifier-list(opt) ) replacement-list new-line
   # define identifier lparen ... ) replacement-list new-line
   # define identifier lparen identifier-list , ... ) replacement-list new-line
replacement-list:
    pp-tokens(opt)

Eine übliche Verwendung sind Inklusionswächter.

#ifndef F_H
# define F_H

#endif

  • Sie haben nicht beantwortet, was der Wert ist FOO nach leer definieren.

    Benutzer1150105

    15. Dezember 2012 um 12:45 Uhr

  • @user14284 Makros haben keine Werte. Sie erweitern sich zu einer Liste von Tokens. Diese Liste kann leer sein.

    – Melpomen

    15. Dezember 2012 um 12:47 Uhr

Leere Makrodefinitionen können auch zur Selbstdokumentation verwendet werden. Das IN im Code-Snippet unten ist ein Beispiel. Der Code und der Kommentar sind beide aus dem zitiert EDK II-Projekt.

//
// Modifiers for Data Types used to self document code.
// This concept is borrowed for UEFI specification.
//

///
/// Datum is passed to the function.
///
#define IN


typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_RESET)(
  IN EFI_BLOCK_IO_PROTOCOL          *This,
  IN BOOLEAN                        ExtendedVerification
  );

  • Ich würde ein anderes Beispiel verwenden. Es muss kein Zitat aus dem tatsächlichen Code sein, aber das aktuelle Beispiel enthält eine ziemlich große Menge unnötiger Informationen. (Stellen Sie übrigens sicher, dass Ihre Antwort immer noch die ursprüngliche Frage beantwortet; sie funktioniert gut mit den anderen Antworten, aber als eigenständige Antwort passt sie nicht wirklich zur Frage “Was tut FOO erweitern zu”?).

    – Zeta

    11. August 2015 um 14:14 Uhr

  • Danke für den Hinweis. Ich lese gerade dieses Stück Code, wenn ich diese Frage sehe. Da die Antwort schon lange ausgewählt wurde, hoffe ich nur, dass meine Antwort als erzieherische Referenz dienen kann.

    – smWikipedia

    11. August 2015 um 14:48 Uhr

1413300cookie-checkSind leere Makrodefinitionen in C erlaubt? Wie verhalten sie sich?

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

Privacy policy