2016-10-28 7 views
0

Ich versuche, ein Makro zu schreiben, um Felder einer komplexen Struktur zu initialisieren. In dieser Struktur ist ein Mitglied ein Zeiger, den ich manchmal mit einer echten Adresse und manchmal zu NULL initialisieren möchte. Die Struktur kann wie folgt vereinfacht werden:Warum ist diese Initialisierung für einen statischen Zeiger nicht gültig?

typedef struct { 
int * p; 
} MYSTRUCT; 

Mein erster Pass auf Makro war:

#define INIT_STRUCT(x) {&(x)} 

und die Verwendung wäre:

static int foo; 
static MYSTRUCT struct1 = INIT_STRUCT(foo); 

Das funktioniert gut, wenn ich initialisieren zu einem echten Zeiger, aber Folgendes funktioniert nicht:

static MYSTRUCT struct2 = INIT_STRUCT(NULL); 

weil es als {&(NULL)} entwickelt wurde und der Compiler (zu Recht) Flags mit & auf einer Konstante als Fehler entwickelt. Ich weiß, dass ich wählen könnte, die & als Teil des Arguments und nicht Teil des Makrokörpers, aber das ist nicht in meinem Fall, und auch ich kann nicht akzeptieren, dass der Compiler gewinnt, so dass ich versucht, klüger mit zu sein die folgende zweite Version des Makros:

static void * NOTHING; 
#define INIT_STRUCT(x) {&NOTHING == &(x) ? NULL : &(x)} 

mit Nutzung

MYSTRUCT struct1 = INIT_STRUCT(foo); 
MYSTRUCT struct2 = INIT_STRUCT(NOTHING); 

jedoch der Compiler Proteste, dass "initializer keine konstante ist". Wenn ich &NOTHING == &(x) durch 1 == 2 ersetze, gibt es keinen Fehler, so dass das Format einer Bedingung nicht das Problem ist. Auf der anderen Seite gelten &NOTHING und &(foo) als Initialisierer für sich.

Korrigiert der Compiler mein "intelligenteres" Makro? Gibt es eine andere Lösung, außer das Schreiben der & als Teil des Arguments für foo?

Der Compiler ist Microsoft Visual Studio C 2010 Ultimate.

+4

Warum das 'INIT_STRUCT' Makro als' #define INIT_STRUCT nicht einfach definieren (x) {(x)} ', und verwenden Sie es als' INIT_STRUCT (& foo) '? Es wird für die Leser des Codes transparenter sein, was passiert, und natürlich würde Ihr Problem mit "NULL" lösen. –

+1

Zusätzlich zu dem, was @Someprogrammerdude sagte, könnten Sie auch 2 Makros definieren; eine für den allgemeinen Fall und eine für den speziellen Fall. Mit Makros zu "schlau" zu werden, sollte vermieden werden, da Makros nicht sehr flexibel sind und später andere Probleme verursachen können. – user694733

Antwort

1

Sie können dies vereinfachen und verwenden.

#define INIT_STRUCT(str, x) {str -> p = x} 

Dies als

verwendet wird
INIT_STRUCT(struct1, foo); 
INIT_STRUCT(struct2, NULL); 
+0

Dies ist eine Zuweisung, keine Initialisierung. Daher wird es nicht mit 'const' Variablen arbeiten. – user694733