#define bei MSPGCC

Gast #177318
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
Gast #177319
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
Gast #177320
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.
Gast #177321
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren