Forum: Compiler & IDEs #define bei MSPGCC


von Karsten Roscher (Gast)


Lesenswert?

Hallo alle zusammen.

Nachdem ich mich jetzt ein bißchem mit dem MSPGCC beschäftigt habe und
sehr zufrieden bin, hab ich doch noch eine kleine Frage. Wie verhält
sich der Compiler eigentlich bei "verschatelten" #define-Anweisungen?
Ich meine sowas...

#define clock 3500000
#define freq (clock * 0.05)

wenn ich jetzt "freq" irgendwo verwende, ersetzt das dann schon der
Präprozessor mit dem endgültigen Wert oder nur mit dem Ausdruck
"(3500000 * 0.05)"? Und was macht der Compiler, wenn ich sowas in den
Quelltext schreiben würde? Also generell bei Ausdrücken, die nur aus
Konstanten bestehen? Man könnte ja auch sowas machen:

#define steps 20
...

if (i < steps+10)...

Mir geht es eben darum, ob es auch in solchen Fällen effizient ist, mit
#define zu arbeiten, oder ob es da eventuell doch gewisse Konstrukte
gibt, die dann die Laufzeit-Performance bzw. das kompilierte Endprodukt
beeinträchtigen.

Ein Blick in den "ausgegebenen" Assemblercode ließ mich ja vermuten,
dass entweder Präprozessor oder Compiler da recht intelligent zu Werke
gehen und das immer gleich durch die entsprechende Konstante ersetzen.
Ist das aber immer so? Vielen Dank schonmal.

Gruß, der Newbie Karsten

von Oliver Rogasch (Gast)


Lesenswert?

Hallo arsten,

der Präprozessor macht eine reine Textersetzung "(3500000 * 0.05)".
Das gilt auch für Konstanten:
#define steps 20
...

if (i < steps+10)...

wird zu:

if (i < 20+10)...

Ob der Compiler daraus jetzt (i < 30) macht glaub ich nicht, da die
Berechnungen erst zur Laufzeit erfolgen. Aber dazu kann sicherlich
jemand anderes noch besser Bescheid wissen.

Gruß

Oliver

von Karsten Roscher (Gast)


Lesenswert?

Also ich habe eben mal ein kurzes Testprogramm geschrieben, was in etwa
wie folgt aussah...

---

#define def_a 20
#define def_b (def_a * 3)

int i, j;

int main()
{
  i = def_a + 10;
  j = def_b;
}

---

Und mir dann den resultierenden Assemblercode angeschaut... da steht
aber explizit nur folgendes:

mov #30, &0x0202
mov #60, &0x0200

Irgendwer (g) scheint also die Ausdrücke zu berechnen, die zur
Compile-Zeit nur aus Konstanten bestehen. Macht ja auch durchaus Sinn.
Hab mir eben nur die Frage gestellt, weil ich ein paar Frequenzen (bzw.
Timer-Schrittweiten) "definen" wollte und das in Abhängigkeit von der
(ebenfalls per #define angegebenen) Basisfrequenz des Timers. Wenn sich
also die Frequenz ändert, braucht man nur einen Wert in der h-Datei zu
ändern. Alles seltsam... ich dachte nämlich bis jetzt auch, dass der
Präprozessor nur textuell ersetzt. Danke trotzdem schonmal.

von Jörg Wunsch (Gast)


Lesenswert?

Jeder ordentliche Compiler berechnet Ausdrücke, die zur Compilezeit
konstant sind, passend vor.  Das ist dann noch Basis für mögliche
Optimierungen, bspw. kann das explizite Laden zweier Bytes:

varhi = (var >> 8);
varlo = (var & 0xff);

durchaus passend optimiert werden, daß einfach entsprechende
Registerzuweisungen benutzt werden, ohne überhaupt irgendwas hin- und
herzuschieben oder mit UND zu verknüpfen.

Auch andere Optimierungen sind sinnvoll und einfach, bspw. kann eine
Division durch (zur Compilezeit konstante) 2**N durch entsprechendes
Rechtsschieben implementiert werden.

von Oliver Rogasch (Gast)


Lesenswert?

Ok, lag ich also doch daneben.
Aber es ist immer wieder schön was dazuzulernen.

Gruß

Oliver

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.