Angenommen, die "leer" MakrodefinitionSind in C leere Makrodefinitionen erlaubt? Wie verhalten sie sich?
#define FOO
Ist es gültig Standard C? Wenn ja, was ist FOO
nach dieser Definition?
Angenommen, die "leer" MakrodefinitionSind in C leere Makrodefinitionen erlaubt? Wie verhalten sie sich?
#define FOO
Ist es gültig Standard C? Wenn ja, was ist FOO
nach dieser Definition?
Es ist einfach ein Makro, das erweitert wird, naja, nichts. Nachdem das Makro jedoch definiert wurde, können Sie mit #if defined
(oder #ifdef
) überprüfen, ob es definiert wurde.
#define FOO
int main(){
FOO FOO FOO
printf("Hello world");
}
expandieren zu
int main(){
printf("Hello world");
}
gibt es bestimmte Situationen, in denen dies in sehr praktisch ist, zum Beispiel zusätzliche Debug-Informationen, die Sie nicht wollen, in Ihrem Release-Version zeigen:
/* 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
definiert wurde, wird DEBUG_MSG(x)
auf print(x)
erweitert und Sie erhalten Entering main
. Wenn Sie die #define
entfernen, wird DEBUG_MSG(x)
zu einer leeren do
- while
Schleife erweitert und Sie werden die Nachricht nicht sehen.
Dies ist sehr riskant, da es Kompilierung vor allem brechen kann. wenn Sie Anweisungen wie '' 'haben, wenn (x) DEBUG_MSG (" test "); sonst DEBUG_MSG ("test"); '' '. Ich bevorzuge es, mein leeres Makro mit einer no-effect-Anweisung zu deklarieren wie '' '#define DEBUG_MSG (x) do {} while (0)' '' – Ely
@Ely ein besseres Beispiel ist ein Header-Guard. Wie auch immer, behoben. – Zeta
Ja, leere Definition ist vom Standard erlaubt.
C11 (n1570), § 6.10 vorverarbeiten Richtlinien
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 gemeinsame Nutzung ist Wachen Inklusion.
Sie haben nicht geantwortet, was der Wert von 'FOO' nach der leeren Definition ist. –
@ user14284 Makros haben keine Werte. Sie erweitern zu einer Liste von Token. Diese Liste kann leer sein. – melpomene
Leere Makrodefinitionen können auch für die Selbstdokumentation verwendet werden. Die IN
im Code-Snippet unten ist ein Beispiel. Der Code und der Kommentar werden beide aus der EDK II project zitiert.
//
// 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. (Übrigens, stellen Sie sicher, dass Ihre Antwort immer noch die ursprüngliche Frage beantwortet; es funktioniert gut mit den anderen Antworten, aber als eigenständige Antwort passt es nicht wirklich zur Frage "Was erweitert' FOO'? "). – Zeta
Danke, dass Sie darauf hingewiesen haben. Ich lese zufällig gerade diesen Code, wenn ich diese Frage sehe. Da die Antwort lange gewählt wurde, hoffe ich nur, dass meine Antwort als eine pädagogische Referenz dienen kann. – smwikipedia
Es ist leere Zeichenfolge, und ja, es ist akzeptabel. – nhahtdh
Nur um darauf hinzuweisen, [hier] (http://stackoverflow.com/q/8592056/557306) eine andere Frage, die eine interessante Verwendung von leeren beinhaltet. – sidyll