mikrocontroller.net

Forum: Compiler & IDEs C-Präprozessor


Autor: Gast (Gast)
Datum:

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

Autor: A. K. (prx)
Datum:

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

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
cpp ist dein freund, oder -E bei CC.

Autor: Naja (Gast)
Datum:

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

Autor: Sven P. (haku) Benutzerseite
Datum:

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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ;-).

Autor: Gast (Gast)
Datum:

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

Autor: zwieblum (Gast)
Datum:

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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@zwieblum: Eben!

Kleine Nebenfrage zu:
#if ((#BAUD_ERROR > 10) || (#BAUD_ERROR < -10))

Was bewirkt die # vor BAUD_ERROR? Ist die zwingend notwendig?

Autor: A. K. (prx)
Datum:

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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zwieblum schrieb:

> und oh wunde der präprozessor rechnet doch ...

Hast du diesen Code mal ausprobiert?
Beispielsweise mit F_CPU=1000000 und GCC.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

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

Autor: Gast (Gast)
Datum:

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

Autor: A. K. (prx)
Datum:

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

Autor: Gast (Gast)
Datum:

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

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.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

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