Forum: Mikrocontroller und Digitale Elektronik Welche Berechnungen erfolgen durch Präprozessor ?


von Rotho (Gast)


Lesenswert?

Hallo,

gegeben sind drei Binärwerte

z.B. so:
1
#define IO_BIT_OQ 0b00000001
2
#define IO_BIT_OB 0b00000010 
3
#define IO_BIT_OD 0b00000100
4
5
void setup() {
6
  byte iBitmaske = IO_BIT_OQ | IO_BIT_OB | IO_BIT_OD;
7
}

Jetzt stellt sich mir die Frage, ob der Ausdruck "byte iBitmaske = 
IO_BIT_OQ | IO_BIT_OB | IO_BIT_OD;" vom Präprosessor vor-berechnet wird, 
oder ob der Compiler das 1:1 ins Programm übernimmt.

Ja, muss mir demn. mal Gedanken machen, in welcher Datei ich den 
compilierten Code vorfinde. Dann kann ich selbst nachsehen und muss euch 
nicht auf den S* gehen mit so bl. Fragen.  ;)

von M.A. S. (mse2)


Lesenswert?

Rotho schrieb:
> Jetzt stellt sich mir die Frage, ob der Ausdruck "byte iBitmaske =
> IO_BIT_OQ | IO_BIT_OB | IO_BIT_OD;" vom Präprosessor vor-berechnet wird,

Der Präprozessor berechnet gar nichts. Er tauscht nur Text gegen anderen 
Text.
Der Compiler berechnet zur Compilierzeit Dinge, wenn er kann.

von Harry L. (mysth)


Lesenswert?

Der Precompiler macht nur Text-Ersetzungen.
Das sollte deine Frage beantworten.

von M.A. S. (mse2)


Lesenswert?

Rotho schrieb:
> Ja, muss mir demn. mal Gedanken machen, in welcher Datei ich den
> compilierten Code vorfinde.

In der Regel kann man C-Compiler (darum geht es hier doch wohl?) dazu 
bringen, den C-Quellcode in Assembler-Quellcode zu übersetzen.
In diesem kannst Du dann nachschauen, was im Detail entstanden ist.

von Rotho (Gast)


Lesenswert?

M.A. S. schrieb:

> In der Regel kann man C-Compiler (darum geht es hier doch wohl?) dazu
> bringen, den C-Quellcode in Assembler-Quellcode zu übersetzen.
> In diesem kannst Du dann nachschauen, was im Detail entstanden ist.

Jepp, das wäre schick. Hast du eine kurze Info parat, wie das geht?

M.A. S. schrieb:
> Der Compiler berechnet zur Compilierzeit Dinge, wenn er kann.

Ja gut, dann halt der Compiler.

Harry L. schrieb:
> Der Precompiler macht nur Text-Ersetzungen.
> Das sollte deine Frage beantworten.

Leider noch nicht ganz.

Gut, dann so gefragt: Wird der Ausdruck als ein Wert compiliert (also 
im Endeffekt "byte iBitmaske = 0b00000111), oder bleibt die 
OR-Verknüpfung im Programm?

von zitter_ned_aso (Gast)


Lesenswert?

Rotho schrieb:
> oder ob der Compiler das 1:1 ins Programm übernimmt.


ich nehme an, er wird das wegoptimieren.


byte maske = 1 | 2 | 4;

wird zu


byte maske = 7;

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

M.A. S. schrieb:
> Der Präprozessor berechnet gar nichts.

Stimmt nicht ganz.  In bedingten Ausdrücken
1
#if BAUD_RATE * 16 > F_CPU

rechnet der Präprozessor tatsächlich. Aber auch nur in diesen.

von Rotho (Gast)


Lesenswert?

zitter_ned_aso schrieb:
> Rotho schrieb:
>> oder ob der Compiler das 1:1 ins Programm übernimmt.
>
>
> ich nehme an, er wird das wegoptimieren.
>
>
> byte maske = 1 | 2 | 4;
>
> wird zu
>
>
> byte maske = 7;

So ist die Frage. Jetzt nur noch die Antwort :-)

Aber ich gehe auch davon aus. Alles andere wäre Quatsch.

von foobar (Gast)


Lesenswert?

> Jepp, das wäre schick. Hast du eine kurze Info parat, wie das geht?

Bei gcc-Aufruf das -c durch ein -S ersetzen - dann wird statt des 
.o-File ein .s-File mit dem Assemblercode erzeugt.

> Gut, dann so gefragt: Wird der Ausdruck als ein Wert compiliert (also
> im Endeffekt "byte iBitmaske = 0b00000111), oder bleibt die
> OR-Verknüpfung im Programm?

Der Vorgang nennt sich Constant Folding und wird selbst bei -O0 
durchgeführt.

https://en.wikipedia.org/wiki/Constant_folding

von zitter_ned_aso (Gast)


Lesenswert?

Jörg W. schrieb:
> In bedingten Ausdrücken

 macht er dann auch irgendwelche Test (Kompatibilität der Datentypen, 
etc.)?

von Ntldr -. (ntldr)


Lesenswert?

zitter_ned_aso schrieb:
> Jörg W. schrieb:
>> In bedingten Ausdrücken
>
>  macht er dann auch irgendwelche Test (Kompatibilität der Datentypen,
> etc.)?

Ob die Datentypen korrekt sind wird schon geprüft, ansonsten aber nicht 
besonders viel (Teilen durch 0 wird noch abgefangen).
1
#define HALLO "Hallo"
2
#if HALLO > 0 
3
#endif

Führt z.B. zu
1
<source>:2:5: error: token ""Hallo"" is not valid in preprocessor expressions

Was man dabei allerdings beachten muss, ist dass undefinierte Makros zu 
0 ausgewertet werden.

von foobar (Gast)


Lesenswert?

>> In bedingten Ausdrücken
>  macht er dann auch irgendwelche Test

https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_4.html#SEC38

von Stefan F. (Gast)


Lesenswert?

M.A. S. schrieb:
> In der Regel kann man C-Compiler (darum geht es hier doch wohl?) dazu
> bringen, den C-Quellcode in Assembler-Quellcode zu übersetzen.
> In diesem kannst Du dann nachschauen, was im Detail entstanden ist.

Es geht noch besser: Man kann sich auch die Ausgabe des Präprozessors 
anschauen, die der C-Compiler compiliert.

Dazu dient die gcc Option -E.

von Einer K. (Gast)


Lesenswert?

zitter_ned_aso schrieb:
> ich nehme an, er wird das wegoptimieren.

Konstante Ausdrücke werden vom Compiler berechnet.
Nicht vom Preprozessor.

von Rotho (Gast)


Lesenswert?

OK. Alle Fragen geklärt.

Danke schön :-)

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.