mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Bernd K. (prof7bit)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <stdio.h>

#define FOO Hallo
#define BAR Welt

#define CAT(a,b) #a " " #b

int main()
{
        printf(CAT(FOO,BAR) "\n");
}

Autor: DPA (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#define STR(X) #X
#define STR_EVAL(X) STR(X)

#define BAZ STR_EVAL(FOO) " " STR_EVAL(BAR)

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

Autor: Bernd K. (prof7bit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
>
> #include <stdio.h>
> 
> #define FOO Hallo
> #define BAR Welt
> 
> #define CAT(a,b) #a " " #b
> 
> int main()
> {
>         printf(CAT(FOO,BAR) "\n");
> }
> 

FOO BAR

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, siehe DPA. Gleiches Prinzip, aber eine Expansionsebene mehr.

: Bearbeitet durch User
Autor: Bernd K. (prof7bit)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Bernd K. (prof7bit)
Datum:

Bewertung
0 lesenswert
nicht 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):
#define foo       1
#define bar       2
#define baz       3

so daß man später das machen kann:
#if VARIANT==foo

#elif VARIANT==bar

#elif VARIANT==baz

#else
    #error "unbekannter wert für VARIANT"
#endif

Wenn man jetzt gcc -DVARIANT=bar sagt wird daraus nach dem Preprozessor:
#if 2==1

#elif 2==2  // <-- der hier ist zutreffend

#elif 2==3

#else
    #error "unbekannter wert für VARIANT"
#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" 
:-(

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.