Forum: Compiler & IDEs Wer rechnet #define aus?


von David H. (davidm)


Lesenswert?

Was pasiert hier?
Die Buffer größe wird vom Preprozessor ermittelt und mit 3 
multipliziert?
Am ende habe ich in FLASH_CB den wert stehen.

#define FLASH_CB           (sizeof(BUFFER) * 3)


hier wird einfach nur im späteren code meinPORT ebend durch PORTD 
ersetzt

#define meinPORT  PORTD;


Und nun die Frage; was passiert hier?
Rechnet der Preprozessor das aus?

#define  FLASH_CB_NUM_32K_BLOCKS        (FLASH_SIZE_CB / 32)

von Ingo (Gast)


Lesenswert?

David Mueller schrieb:
> Rechnet der Preprozessor das aus?
Ja

von (prx) A. K. (prx)


Lesenswert?

David Mueller schrieb:
> Die Buffer größe wird vom Preprozessor ermittelt und mit 3
> multipliziert?

Eigentlich vom Compiler.

> #define meinPORT  PORTD;

Das ; würde ich mal überdenken.

von (prx) A. K. (prx)


Lesenswert?


von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Es ist eine reine Textersetzung, FLASH_CB_NUM_32K_BLOCKS wird im
Quelltext durch (FLASH_SIZE_CB / 32) ersetzt. Da wird nichts gerechnet.

von Uwe (de0508)


Lesenswert?

Hi,

#define sind in dieser Darstellung nur ein Textersatz im C Quelltext 
durch den Präprozessor, mehr nicht.

Ok?

von Roland .. (rowland)


Lesenswert?

Und "(FLASH_SIZE_CB / 32)" rechnet dann der Compiler aus, sofern 
"FLASH_SIZE_CB" auch eine Konstante ist.

von B. S. (bestucki)


Lesenswert?

A. K. schrieb:
> Ingo schrieb:
>> David Mueller schrieb:
>>> Rechnet der Preprozessor das aus?
>> Ja
> Nein.

Was aber nicht bedeutet, dass der Präprozessor nicht rechnen kann, denn 
folgender Code wird einen Fehler produzieren:
1
#define VALUE_A 1000
2
#define RESULT (VALUE_A/5)
3
4
#if RESULT>100
5
  #error RESULT ist zu gross
6
#endif

Steht RESULT irgendwo im Code, rechnet das natürlich der Compiler aus.

von (prx) A. K. (prx)


Lesenswert?

be stucki schrieb:
> Was aber nicht bedeutet, dass der Präprozessor nicht rechnen kann, denn
> folgender Code wird einen Fehler produzieren:

Korrekt. Aber die Bedingung eines #(els)if Statements ist die einzige 
Stelle, an der der Präprozessor rechnet. Sehe viele Anfänger gehen 
jedoch davon aus, dass er auch in #define rechnet. Und das tut er nicht.

von David H. (davidm)


Lesenswert?

eeeh OK, vielen Dank für die Tips.
Wenn es der compiler rechnet...

Erreicht werden soll das der compiler das rechnet
und nicht die MCU zur laufzeit.

Wie kann man das im code klar machen das es wirklich der 
preprozessor/compiler macht?
1
void rechne(void) {
2
 BYTE x;
3
 x = 10 + 2;
4
}
5
6
void rechne(void) {
7
 const BYTE x = 10;
8
 x += 2;
9
}
10
11
// Wie ist es hier? Rechnet das der Compiler vorher?
12
#define y 10
13
14
void rechne(void) {
15
 x = y + 2;
16
}

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


Lesenswert?

David Mueller schrieb:
> Wie kann man das im code klar machen das es wirklich der
> preprozessor/compiler macht?

Gar nicht.

Das ist immer eine Entscheidung des Compilers.

Du kannst aber getrost davon ausgehen, dass er Ausdrücke, die ganz
eindeutig zur Compilezeit bekannt (und konstant) sind, auch da bereits
ausrechnet, sofern du mindestens mit -O1 compilierst.

von Stefan E. (sternst)


Lesenswert?

Jörg Wunsch schrieb:
> Du kannst aber getrost davon ausgehen, dass er Ausdrücke, die ganz
> eindeutig zur Compilezeit bekannt (und konstant) sind, auch da bereits
> ausrechnet, sofern du mindestens mit -O1 compilierst.

Nur so als Info: Constant-Folding wird auch schon bei -O0 gemacht.

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


Lesenswert?

Stefan Ernst schrieb:
> Nur so als Info: Constant-Folding wird auch schon bei -O0 gemacht.

Teils, teils.  Die Gleitkommaargumente von _delay_ms() etc. werden
halt bei -O0 nicht zur Compilezeit aufgelöst, weshalb man diese
Funktionen immer mit aktivierter Optimierung benutzen muss.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Stefan Ernst schrieb:
>> Nur so als Info: Constant-Folding wird auch schon bei -O0 gemacht.
>
> Teils, teils.  Die Gleitkommaargumente von _delay_ms() etc. werden
> halt bei -O0 nicht zur Compilezeit aufgelöst,

Dabei handelt es sich aber nicht um ein reines Constant-Folding, es sind 
z.B. noch (inline) Funktionen zwischengeschaltet.

von Matthias H. (hallamen)


Lesenswert?

Eine garantierte Auswertung zur Compile-time gibt es seit C++11 (avr-gcc 
ab Version 4.8) mit dem 'constexpr'-Konstrukt.
Siehe z.Bsp. hier:
http://www.cprogramming.com/c++11/c++11-compile-time-processing-with-constexpr.html

Damit kann man nun erstmals auf Preprozessor-Makros verzichten!

Anmerkung: Man muss deswegen jedoch nicht alles auf C++11 umzustellen. 
Für die allermeisten Fälle sind die C-Compiler klug genug.

von Peter D. (peda)


Lesenswert?

Es werden aber nur die 4 Grundrechenarten zur Compilezeit ausgeführt, 
höhere Funktionen (pow, sin, log usw.) nicht.

von Stefan E. (sternst)


Lesenswert?

Peter Dannegger schrieb:
> Es werden aber nur die 4 Grundrechenarten zur Compilezeit ausgeführt,
> höhere Funktionen (pow, sin, log usw.) nicht.

Doch, auch die.

Solltest du anderes beobachten, dann benutzt du wohl -ffreestanding.

von (prx) A. K. (prx)


Lesenswert?

Peter Dannegger schrieb:
> Es werden aber nur die 4 Grundrechenarten zur Compilezeit ausgeführt,
> höhere Funktionen (pow, sin, log usw.) nicht.

Doch, auch die werden u.U. bereits vom Compiler berechnet.
Nur ist da weniger Verlass drauf.

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.