Forum: Compiler & IDEs Token Pasting mit SDCC


von Thomas Z. (usbman)


Lesenswert?

ich benutze schon seit vielen Jahren folgendes Makro auf verschiedenen c 
Compilern um eine Zeile in eine leere Anweisung + Kommentar zu 
expandieren.
1
  #define PRINTF ;/##/
2
aus
3
  PRINTF ("blablub"); 
4
wird dann 
5
  ;//("blablub");
Das funktioniert mit div Borland Compilern aber auch mit Keil c51. Das 
Konstrukt geht aber weder mit SDCC noch mit GCC (ARM).

Offensichtlich ist bei modernen Preprozessoren das anders gelöst. Wie 
macht man das richtig?

Ich suche nun nach einem alternativen Weg sowas zu implementieren.

Thomas

von Rolf M. (rmagnus)


Lesenswert?

Thomas Z. schrieb:
> Offensichtlich ist bei modernen Preprozessoren das anders gelöst.

Es ist eigentlich gar nicht Standard-konform.
Der Compiler arbeitet den Code in mehreren Phasen ab. In Phase 3 werden 
alle Kommentare durch jeweils ein Leerzeichen ersetzt. Erst danach, in 
Phase 4 werden dann die Präprozessor-Direktiven inklusive dem 
Token-Pasting-Operator bearbeitet.

: Bearbeitet durch User
von Jim M. (turboj)


Lesenswert?

Für gcc:
1
#define PRINTF(...)

Siehe gcc doku: Variadic Macros.

von Thomas Z. (usbman)


Lesenswert?

Rolf M. schrieb:
> Es ist eigentlich gar nicht Standard-konform.
> Der Compiler arbeitet den Code in mehreren Phasen ab. In Phase 3 werden
> alle Kommentare durch jeweils ein Leerzeichen ersetzt. Erst danach, in
> Phase 4 werden dann die Präprozessor-Direktiven inklusive dem
> Token-Pasting-Operator bearbeitet.

Dass irgendwas nicht standard konform ist ist mir inzwischen auch klar. 
Ich hab das bisher einfach angewendet ohne genauer darüber nachzudenken. 
Jetzt versuche einen Quellcode sowohl für Keil c51 als auch für SDCC 
umzubauen.
Deine Erklärung kann so nicht vollständig sein...
In Phase 3 gibt's ja noch keinen Kommentar der wird erst in Phase 4 
erzeugt. Ich muss mir mal die Präprozessor Ausgaben näher ansehen.

Jim M. schrieb:
> Siehe gcc doku: Variadic Macros.
Das PRINTF ist nur ein Beispiel. Es geht mir nicht um Variadic Makros. 
Trotzdem danke für den Hinweis.

von Rolf M. (rmagnus)


Lesenswert?

Thomas Z. schrieb:
> Dass irgendwas nicht standard konform ist ist mir inzwischen auch klar.
> Ich hab das bisher einfach angewendet ohne genauer darüber nachzudenken.

Was ich damit sagen wollte: Es hat sich eigentlich nichts geändert, 
sondern der bisherige Compiler war halt irgendwie anders umgesetzt, so 
dass es trotzdem funktioniert hat.

> Deine Erklärung kann so nicht vollständig sein...
> In Phase 3 gibt's ja noch keinen Kommentar der wird erst in Phase 4
> erzeugt.

Ja, eben. In Phase 3 werden eigentlich alle Kommentare entfernt, so dass 
es danach keine mehr gibt. Du versuchst dann aber, in Phase 4 wieder 
einen zu erzeugen. An der Stelle gibt es aber das Konzept von 
Kommentaren gar nicht mehr. Deshalb kann der Compiler damit nichts 
anfangen.

von Thomas Z. (usbman)


Lesenswert?

Ich hab mir jetzt mal den Preprozessor Output angesehen. Da steht 
folgendes
1
   ;/ /("blablub");
Fehlermeldung ist:

error pasting"/" and "/" does not give a valid preprocessing token

Der Preprozessor fügt ein space ein. Es sieht so aus als wenn "/" 
ungültige Zeichen sind.

von Thomas Z. (usbman)


Lesenswert?

ok ich hab gefunden warum das nicht geht
https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html
dort wird explizit die Verwendung als comment ausgeschlossen...

von Rolf M. (rmagnus)


Lesenswert?

Thomas Z. schrieb:
> Der Preprozessor fügt ein space ein. Es sieht so aus als wenn "/"
> ungültige Zeichen sind.

Nein, ein "/" nicht (sonst könnte man nicht dividieren), aber zwei am 
Stück schon, denn die hätten ja eigentlich schon eine Phase vorher alle 
entfernt worden sein müssen.

Thomas Z. schrieb:
> dort wird explizit die Verwendung als comment ausgeschlossen...

Ja, und die Erklärung dafür ist die selbe, die ich gegeben habe…

von Thomas Z. (usbman)


Lesenswert?

Die Lösung für mein Problem hab ich inzwischen auf Stackoverflow 
gefunden. Da hätte ich gleich suchen sollen...

https://stackoverflow.com/questions/8742270/how-to-remove-all-debug-printf-statements-from-c-code

Das werde ich adaptieren, das ist ja nicht auf printf begrenzt.

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.