Forum: Mikrocontroller und Digitale Elektronik C Präprozessor Macro Zahlenwert ausgeben, aber wie?


von nur malso (Gast)


Lesenswert?

Hallo,

Ich habe ein "kleines" Problem bei der Erstellung eines Macros in ANSI C

es gibt ja die Möglichkeit mittels "stringizing" den Wert eines #define 
als String zurück zu liefern.
1
#define STR_HELPER(x) #x
2
#define STR(x) STR_HELPER(x)

Nun habe ich aber eine #define welches nicht direkt einen Zahlenwert 
beinhaltet sondern auf ein anderes #define zurückgreift (bsp. siehe 
unten).
gibt es die Möglichkeit zunächst den Wert "berechnen" zu lassen und dann 
ausgeben zu lassen?
1
#define VAR_A 34 // 0x22 
2
#define VAR_B VAR_A
3
#define VAR_C (VAR_A)
4
#define VAR_D (VAR_A&0x0F)
5
6
STR(VAR_A) // -> "34"
7
STR(VAR_B) // -> "34"
8
STR(VAR_C) // -> "(34)"
9
STR(VAR_D) // -> "(VAR_A&0x0F)"
10
11
#if (VAR_D == 2)
12
#define VAR_D_STATE "D true"
13
#else
14
#define VAR_D_STATE "D false"
15
#endif
16
// VAR_D_STATE -> "D true"

Wie an der Abfrage zu sehen ist, ist der "richtige" Wert bzw. Berechnung 
in VAR_D enthalten.

Die Frage ist nun, habe ich irgend eine Möglichkeit diesen Wert als 
String zu bekommen?

Mittlerweile bin ich fast so weit folgendes zu schreiben
1
#if (VAR_D == 0)
2
#define VAR_D_S "0"
3
#elif (VAR_D == 1)
4
#define VAR_D_S "1"
5
.
6
.
7
.
8
#elif (VAR_D == 99)
9
#define VAR_D_S "99"

Aber es muss doch eine elegantere Methode geben, oder?

PS.: ich weiß im obigen Beispiel geht VAR_D nur bis 0x0F und nicht bis 
99, allerdings dient die Variable auch nur der Veranschaulichung.

Vielen Dank im voraus

von Micha (nichtgast)


Lesenswert?

Moin,

spontan lautet die Anwort: Nein

der Präprozessor macht nur reine Textersetzung und kann keine Ausdrücke 
auswerten.

Grüße,

von Vincent H. (vinci)


Lesenswert?

Mit Hilfe von Boost geht das schon, aber nur mit ziemlich abgefuckter 
Präprozessor Magie: https://godbolt.org/z/8NmRI2

Wenn du die Auswertung von Ausdrücken zur Compilezeit brauchst, dann ist 
C++ das bessere Tool für deine Anwendung.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

die Frage ist was man unter Auswertung versteht. Serial ausgeben geht an 
der Stelle noch nicht. Aber der Compiler kann dir das ausgeben.

Bsp. dazu wäre die Baudrateneinstellung
1
// UART Berechnungen des Wertes für das Baudratenregister aus Taktrate und gewünschter Baudrate
2
#define UART_BAUD_RATE  250000UL    // gewünschte Baudrate
3
#define UBRR_VAL ((F_CPU+UART_BAUD_RATE*8)/(UART_BAUD_RATE*16)-1)  // sauber runden
4
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))              // reale Baudrate
5
#define BAUD_ERROR ((BAUD_REAL*1000)/UART_BAUD_RATE)        // Fehler in Promille, 1000 = kein Fehler.
6
#if ((BAUD_ERROR<995) || (BAUD_ERROR>1005))
7
  #error Systematischer Fehler der Baudrate groesser 0,5% und damit zu hoch! 
8
#endif

Wenn Fehler außerhalb der Toleranz erscheint im Compilerfenster 
nachfolgender Text inkl. Abbruch.

Edit:
Wollte damit sagen mit dem Befehl error kannste eine! Ausgabe erzeugen. 
Eine andere Möglichkeit sehe ich nicht.

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.