Forum: Compiler & IDEs Preprozessor-Rätsel (Stringliteral erzeugen)


von Bernd K. (prof7bit)


Lesenswert?

gegeben ist folgendes:

gcc -DFOO=hallo -DBAR=welt ...

jetzt möchte ich gerne im Code stehen haben

#define BAZ    simsalabim(FOO, BAR)

und der hier stellvertretend mit simsalabim umschriebene Ausdruck soll 
so funktionieren daß BAZ hinterher zu "hallo welt" (mitsamt den Quotes) 
expandiert. Ist das überhaupt möglich, und wenn ja was muss ich an der 
Stelle hinschreiben?

von (prx) A. K. (prx)


Lesenswert?

1
#include <stdio.h>
2
3
#define FOO Hallo
4
#define BAR Welt
5
6
#define CAT(a,b) #a " " #b
7
8
int main()
9
{
10
        printf(CAT(FOO,BAR) "\n");
11
}

von DPA (Gast)


Lesenswert?

Ganz genau das ist nicht möglich, aber beachte, dass "hallo" " " "welt" 
vom Kompiler in der regel bleich behandelt wird wie "hallo welt". Wenn 
FOO und BAR garantiert immer nur alphanumerische Zeichen enthalten, also 
keine Sonderzeichen enthalten, könnte man sowas versuchen:
1
#define STR(X) #X
2
#define STR_EVAL(X) STR(X)
3
4
#define BAZ STR_EVAL(FOO) " " STR_EVAL(BAR)

Andernfalls könntest du auch die Quotes bei FOO und BAR schon mitgeben:
1
gcc -DFOO='"hallo"' -D'BAR='"welt"'
Und dann:
1
#define BAZ FOO " " BAR

von Bernd K. (prof7bit)


Lesenswert?

A. K. schrieb:
>
1
> #include <stdio.h>
2
> 
3
> #define FOO Hallo
4
> #define BAR Welt
5
> 
6
> #define CAT(a,b) #a " " #b
7
> 
8
> int main()
9
> {
10
>         printf(CAT(FOO,BAR) "\n");
11
> }
12
>

FOO BAR

von (prx) A. K. (prx)


Lesenswert?

Stimmt, siehe DPA. Gleiches Prinzip, aber eine Expansionsebene mehr.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Ja, die Lösung von DPA funktioniert.
Danke.

Quotes direkt bei den -DSYMBOL=WERT kann ich leider nicht machen weil da 
noch etliche #if überall dranhängen die ich nicht ändern will und das 
mit den Strings auch nur ein zusätzliches Sahnehäubchen sein soll, nicht 
der Hauptverwendungszweck der Defines.

Die Defines sind Namen für Varianten und Untervarianten einer Firmware 
die alle automatisch gebaut werden und die soll unter anderem auch einen 
String ausgeben können an dem man später unkompliziert ablesen kann 
welche Variante da draufgeflasht wurde. Als damals noch nur 3 mögliche 
Kombinationen überhaupt existierten hatte ich diese Strings einfach hart 
kodiert aber jetzt werden noch mehr Varianten und Untervarianten 
hinzukommen und im Zuge des vorauseilenden Refactorns etlicher nun 
drohender #if/#elif-Monster will ich das kein zweites mal mehr anfassen 
müssen und so soll unter anderem der String jetzt automatisch generiert 
werden.

: Bearbeitet durch User
von Bernd K. (prof7bit)


Lesenswert?

Verflucht!

Das geht auch nicht so wie ich mir das vorstelle.

Denn damit die ganzen #if die über den ganzen Code versprenkelt sind 
auch funktionierten sind in einem zentralen Header all den erlaubten 
Strings die man da reinfüttern kann numerische Werte zugewiesen (damit 
Vergleiche im Preprozessor funktionieren):
1
#define foo       1
2
#define bar       2
3
#define baz       3

so daß man später das machen kann:
1
#if VARIANT==foo
2
3
#elif VARIANT==bar
4
5
#elif VARIANT==baz
6
7
#else
8
    #error "unbekannter wert für VARIANT"
9
#endif

Wenn man jetzt gcc -DVARIANT=bar sagt wird daraus nach dem Preprozessor:
1
#if 2==1
2
3
#elif 2==2  // <-- der hier ist zutreffend
4
5
#elif 2==3
6
7
#else
8
    #error "unbekannter wert für VARIANT"
9
#endif

Jetzt komm ich natürlich nicht mehr an meine ursprünglichen sprechenden 
Variantennamen ran weil das alles sofort durch die Zahlenwerte ersetzt 
wird. Aus meinem erhofften "hallo welt" wird dann sofort sowas wie "2 4" 
:-(

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.