2009-07-22 8 views
7

Ich habe ein C-Programm mit vielen Optimierungen, die mit #define s aktiviert oder deaktiviert werden können. Wenn ich mein Programm starte, würde ich gerne wissen, welche Makros zur Kompilierzeit definiert wurden.Name und Wert eines Makros drucken

Also versuche ich eine Makrofunktion zu schreiben, um den tatsächlichen Wert eines Makros zu drucken. Etwas wie folgt aus:

SHOW_DEFINE(X){\ 
    if(IS_DEFINED(X))\ 
     printf("%s is defined and as the value %d\n", #X, (int)X);\ 
    else\ 
     printf("%s is not defined\n", #X);\ 
} 

aber ich weiß nicht, wie es funktioniert, und ich vermute, dass es nicht möglich ist, hat jemand eine Idee, wie es zu tun hat?

(Beachten Sie, dass dies muss auch kompilieren, wenn das Makro nicht definiert ist!)

Antwort

4

Das Schreiben eines MACRO, das zu einem anderen MACRO erweitert wird, würde erfordern, dass der Präprozessor zweimal ausgeführt wird.
Das ist nicht getan.

Sie eine einfache Datei schreiben konnte,

// File check-defines.c 
int printCompileTimeDefines() 
{ 
#ifdef DEF1 
    printf ("defined : DEF1\n"); 
#else // DEF1 
    printf ("undefined: DEF1\n"); 
#endif // DEF1 
// and so on... 
} 

Verwenden Sie die gleiche Kompilierzeit Linien zu dieser Datei definieren wie bei den anderen Dateien.
Rufen Sie die Funktion irgendwann beim Start auf.

Wenn Sie die #DEFINE Linien innerhalb einer Quelldatei haben, anstatt die Makefile,
Verschieben Sie sie in einen anderen Header Datei und schließen diesen Header in allen Quelldateien,
einschließlich dieses check-defines.c.

Hoffentlich haben Sie die gleiche Anzahl von definierten Definitionen für alle Ihre Quelldateien.
Andernfalls wäre es ratsam, die Strategie Ihrer definiert erneut zu überprüfen.


Um automatisieren Generation dieser Funktion,
Sie die M4 Makrosprache (oder sogar ein AWK script tatsächlich) nutzen könnten.
M4 wird Ihr Pre-Pre-Prozessor.

+0

Akzeptiert für die Antwort von m4. Dies wird leicht, wenn Sie einen weiteren Vorverarbeitungsschritt hinzufügen. Ich habe SHOW_DEFINE (X, Y, Z ...) gemacht, was noch besser ist. Aber es macht Sens, weil ich m4 für andere Sachen brauche. – Ben

2
#ifdef MYMACRO 
    printf("MYMACRO defined: %d\r\n", MYMACRO); 
#endif 

glaube ich nicht, was Sie zu tun versuchen, ist möglich. Sie fragen zur Laufzeit nach Informationen, die vor der Übersetzung bearbeitet wurden. Die Zeichenfolge "MYMACRO" bedeutet nichts, nachdem CPP sie innerhalb des Programms auf ihren Wert erweitert hat.

+0

Nun, das möchte ich vermeiden, da ich viele davon mit #ifdef #else #endif habe. – Ben

2

Sie haben den von Ihnen verwendeten Compiler nicht angegeben. Wenn dies gcc ist, kann Ihnen gcc -E helfen, da es nach der Vorverarbeitungsstufe stoppt und das Vorverarbeitungsergebnis ausgibt. Wenn Sie ein gcc -E-Ergebnis mit der Originaldatei vergleichen, erhalten Sie möglicherweise einen Teil von dem, was Sie wollen.

2

Warum nicht einfach mit dem Präprozessor testen?

#if defined(X) 
     printf("%s is defined and as the value %d\n", #X, (int)X); 
#else 
     printf("%s is not defined\n", #X); 
#endif 

Man kann auch einbetten dieser in einem anderen Test es nicht jedes Mal zu drucken:

#if define(SHOW_DEFINE) 
#if defined(X) 
     printf("%s is defined and as the value %d\n", #X, (int)X); 
#else 
     printf("%s is not defined\n", #X); 
#endif 
#endif 
+0

@philippe, Nun, das scheinen mir und Kjfletch vorgeschlagen zu haben. Aber er möchte vermeiden, alles niederzuschreiben, weshalb ich M4 oder AWK Scripting vorschlage. – nik

+0

Dies ist, was ich jetzt mache, die Liste ist nie auf dem neuesten Stand und es braucht eine spezielle Datei nur für diesen Zweck :( – Ben

1

Wave library von Boost nützlich auch sein kann, zu tun, was Sie wollen.Wenn Ihr Projekt groß genug ist, denke ich, dass es einen Versuch wert ist. Es ist ein C++ - Präprozessor, aber sie sind alle gleich :)

1

Ich glaube, was Sie versuchen, ist nicht möglich. Wenn Sie in der Lage sind, die Art und Weise arbeiten, um Ihre #define s zu ändern, dann schlage ich etwas wie folgt aus:

#define ON 1 
#define OFF 2 

#define OPTIMIZE_FOO ON 
#define OPTIMIZE_BAR OFF 

#define SHOW_DEFINE(val)\ 
    if(val == ON) printf(#val" is ON\n");\ 
    else printf(#val" is OFF\n"); 
1

Es ist in der Tat nicht möglich, das Problem der „nicht definiert“ Teil zu sein. Wenn Sie auf die Makrowerte verlassen würde zu aktivieren/deaktivieren Teile des Codes, dann könnte man einfach tun:

#define SHOW_DEFINE(X) \ 
do { \ 
if (X > 0) \ 
    printf("%s %d\n", #X, (int)X); \ 
else \ 
    printf("%s not defined\n", #X); \ 
} while(0) 
25

Solange Sie bereit sind, mit der Tatsache zu setzen, dass somestring = somestring dass somestring zeigt nicht definiert wurde (!?! hat sehen es als das Token neu definiert nicht), dann sollte folgendes tun:

#include <stdio.h> 

#define STR(x) #x 
#define SHOW_DEFINE(x) printf("%s=%s\n", #x, STR(x)) 

#define CHARLIE -6 
#define FRED 1 
#define HARRY FRED 
#define NORBERT ON_HOLIDAY 
#define WALLY 

int main() 
{ 
    SHOW_DEFINE(BERT); 
    SHOW_DEFINE(CHARLIE); 
    SHOW_DEFINE(FRED); 
    SHOW_DEFINE(HARRY); 
    SHOW_DEFINE(NORBERT); 
    SHOW_DEFINE(WALLY); 

return 0; 
} 

die Ausgabe lautet:

BERT=BERT 
CHARLIE=-6 
FRED=1 
HARRY=1 
NORBERT=ON_HOLIDAY 
WALLY= 
+1

Nice! – Ben

+0

Und ich habe gerade einen Weg gefunden, die 15 Zeichen Kommentar Begrenzung zu umgehen .. – Ben

0

auf Chrisharris Basierend Antwort, die ich tat Dies. Obwohl meine Antwort nicht sehr nett ist, ist es ziemlich, was ich wollte.

Nur der Fehler, den ich gefunden habe, ist die Definition muss nicht #define XXX XXX (mit XXX ist gleich XXX).

0

Sie können eine Integer-Variable verwenden, die mit 1 initialisiert wurde. Multiplizieren Sie das #define mit dieser Variablen und drucken Sie den Wert der Variablen.