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)
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.
Ingo schrieb: > David Mueller schrieb: >> Rechnet der Preprozessor das aus? > Ja Nein. http://www.mikrocontroller.net/articles/C-Präprozessor
Es ist eine reine Textersetzung, FLASH_CB_NUM_32K_BLOCKS wird im Quelltext durch (FLASH_SIZE_CB / 32) ersetzt. Da wird nichts gerechnet.
Hi, #define sind in dieser Darstellung nur ein Textersatz im C Quelltext durch den Präprozessor, mehr nicht. Ok?
Und "(FLASH_SIZE_CB / 32)" rechnet dann der Compiler aus, sofern "FLASH_SIZE_CB" auch eine Konstante ist.
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.
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.
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 | }
|
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.
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.
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.
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.
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.
Es werden aber nur die 4 Grundrechenarten zur Compilezeit ausgeführt, höhere Funktionen (pow, sin, log usw.) nicht.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.