Re: Preprocessor-Direktiven im Inneren eines Makros
David Haller <[email protected]>
| Newsgroups | gmane.linux.suse.programming |
|---|---|
| Message-ID | <[email protected]> |
Hello,
On Tue, 29 Jul 2008, Tilman Schmidt wrote:
>Ich würde gerne ein Makro bauen, das
>
>TABLE_ENTRY(FOO)
>
>zu
>
>#ifdef N_FOO
>{ "FOO", N_FOO },
>#endif
>
>expandiert - also einen Tabelleneintrag generiert, falls
>das Preprocessor-Symbol N_xyz definiert ist. Ziel ist,
>dass ich nachher im Programm schreiben kann:
>
>static const struct { const char *s; int v; } table[] = {
>TABLE_ENTRY(FOO)
>TABLE_ENTRY(BAR)
>TABLE_ENTRY(BAZ)
>TABLE_ENTRY(TOTO)
>TABLE_ENTRY(TITI)
>TABLE_ENTRY(TATA)
>};
>
>und table[] dann genau die Einträge enthält, für die der
>entsprechende Wert auch definiert ist.
>
>Die Expansion
> TABLE_ENTRY(FOO) => { "FOO", N_FOO },
>ist ja kein Problem, aber die Abfrage, ob N_FOO definiert
>ist, also das #ifdef - #endif außenrum, will nicht klappen.
>Wenn ich so etwas wie
>
>#define TABLE_ENTRY(x) \
>#ifdef N_##x \
>{ #x, N_##x }, \
>#endif
>
>versuche, beschwert sich CPP:
>
>t.c:2:3: error: '#' is not followed by a macro parameter
>
>Ideen?
Mehrstufig. Erklären kann ich jetzt grad nicht *gähn*:
==== t.c ====
#define N_FOO 1
#define N_BAZ 4
#ifdef N_FOO
#define _TABLE_ENTRY_FOO { "FOO", N_FOO },
#else
#define _TABLE_ENTRY_FOO
#endif
#ifdef N_BAR
#define _TABLE_ENTRY_BAR { "BAR", N_BAR },
#else
#define _TABLE_ENTRY_BAR
#endif
#ifdef N_BAZ
#define _TABLE_ENTRY_BAZ { "BAZ", N_BAZ },
#else
#define _TABLE_ENTRY_BAZ
#endif
#define TABLE_ENTRY(x) _TABLE_ENTRY_ ## x
static const struct { const char *s; int v; } table[] = {
TABLE_ENTRY(FOO)
TABLE_ENTRY(BAR)
TABLE_ENTRY(BAZ)
{ NULL, 0 }
};
====
$ cpp t.c | sed '/^$/d'
# 1 "t.c"
static const struct { const char *s; int v; } table[] = {
{ "FOO", 1 },
{ "BAZ", 4 },
{ NULL, 0 }
};
Das sollte doch sein, was du suchst, odr?
Evtl. könnte man, je nach dem was die Expansion der Makros sein soll,
weiter makroisieren...
-dnh
--
Life is full of small and large disappointments, and then you die.
-- M. Andrews