Ich mache in meinem Code ein paar Berechnungen mit dem C-Präprozessor. Gibt es eine einfache Möglichkeit, die Ergebnisse (also den Inhalt von Makros) auszugeben. Bekannt ist mir die Methode, Makros mit dem gdb zu evaluieren. Kann man die Inhalte von Makros nicht irgenwie beim Compilieren ausgeben (ähnlich wie mit Texten bei #error oder #warning)? Vielen Dank im Voraus für eure Antworten.
Eher nicht, denn ich bezweifle mal, dass du tatsächlich irgendwas mit dem Präprozessor berechnest. Die einzige Stelle wo der selber rechnet ist das #if Statement.
Es gibt bei den meisten Compilern einen Startparameter, der es erlaubt nur die Präprozessor Makros zu expandieren. Das ergibt zwar nicht das selbe Verhalten wie bei #error oder #message sollte aber helfen.
Der Präprozessor ist so ein Ding, das man vor 15 Jahren schon hätte wegwerfen sollen. Wenn möglich, berechne lieber in C und vertrau ein ganz klein wenig auf die Fähigkeiten des Optimierers.
Sven P. schrieb: > Wenn möglich, berechne lieber in C und vertrau ein > ganz klein wenig auf die Fähigkeiten des Optimierers. Ich bin ziemlich sicher, dass er genau das tut, ohne es zu wissen ;-).
@A. K.: Genau um das #if-Statement geht es mir. Ich mache eine kleine Berechnung ähnlich der in der avr-libc zum Baudraten-Fehler und möchte eine Warnung ausgeben. Zur Kontrolle hätte ich halt gerne, den berechneten Wert mit der Warnung ausgegeben.
#define BAUD 115200UL #if F_CPU < 2000000UL && defined(U2X) UCSR0A = _BV(U2X); // improve baud rate error by using 2x clk UBRR0L = (F_CPU / (8UL * BAUD)) - 1; #else UCSR0A = 0; UBRR0L = (F_CPU / (16UL * BAUD)) - 1; #endif UCSR0B = _BV(TXEN0) | _BV(RXEN0); // tx/rx enable UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); // 8 Bit #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) #if ((#BAUD_ERROR > 10) || (#BAUD_ERROR < -10)) #error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!" #endif und oh wunde der präprozessor rechnet doch ...
@zwieblum: Eben! Kleine Nebenfrage zu: #if ((#BAUD_ERROR > 10) || (#BAUD_ERROR < -10)) Was bewirkt die # vor BAUD_ERROR? Ist die zwingend notwendig?
zwieblum schrieb:
> und oh wunde der präprozessor rechnet doch ...
Im #if tut er das, das hatte schon geschrieben, aber er tut es nur dort.
Überall sonst reicht er die Rechnung 1:1 an den Compiler weiter.
zwieblum schrieb:
> und oh wunde der präprozessor rechnet doch ...
Hast du diesen Code mal ausprobiert?
Beispielsweise mit F_CPU=1000000 und GCC.
Gast schrieb: > Gibt es eine einfache Möglichkeit, die Ergebnisse (also den Inhalt von > Makros) auszugeben. gcc -E -dM Gibt allerdings nur den Wert am Schluss aus, wenn ein Makro zwischen- zeitlich verschiedene Werte hat, kann man das damit nicht verfolgen. Ansonsten erfindest du natürlich das Fahrrad nur gerade zum 42. Mal, siehe <util/setbaud.h>.
@Jörg: Die Baudratenrechnung hatte ich nur als Beispiel genommen, weil ich bei meiner Rechnung analog vorgehe und die jeder kennen duerfte. Meinen Anwendungsfall habe ich nicht gepostet, um Diskussionen über Sinn und Zweck zu vermeiden. setbaud.h nutze ich ;) Aber um mal bei dem Beispiel von Zwieblum zu bleiben: Wenn BAUD_REAL und BAUD definiert sind, wie kann ich das Ergebnis von #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) anzeigen lassen? BAUD_ERROR wird ja nur vom Präprozessor in einer #if-Direktive ausgewertet. gcc -E -dM scheint da nicht zu helfen. Danke.
long x = BAUD_ERROR; gcc -S source.c und im Resultat nach dem Initialisierungswert der Variable suchen. Kleiner Nachteil: Der Wert stammt vom Compiler, nicht vom Präprozessor. Die können unterschiedlicher Ansicht sein weil unabhängig voneinander ausgewertet (sollten zwar nicht, aber...).
@A.K.: Danke. So habe ich mir bisher geholfen. Allerdings den Wert von x dann im gdb angeschaut. So ist aber nochmal einfacher. Scheint wohl keine einfachere Moeglichkeit zu geben. Vielen Dank an alle.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.