dieses schlägt jedoch fehl, da an das Makro nur ein (anstatt zwei)
Parameter übergeben wird. Anscheinend wird SET_PIN vor PIN_LED
substituiert.
Lässt sich das Verhalten irgendwie so ändern, dass das Makro innerhalb
der Klammern vor dem äusseren makro aufgelöst wird?
Am Rande: ich möchte dieses Funktionalität bewusst mit Makros (und nicht
Funktionen) implementieren. Ein "Inlinen" der Funktion hat nicht immer
zum gewünschten Resultat geführt, manchmal scheint der Compiler trotzdem
einen Funktionsaufruf einzufügen.
Oliver S. schrieb:> Ein "Inlinen" der Funktion hat nicht immer> zum gewünschten Resultat geführt, manchmal scheint der Compiler trotzdem> einen Funktionsaufruf einzufügen.
Das lässt sich (zumindest beim GCC) so beheben:
Oliver S. schrieb:> Parameter nun ebenfalls als Makro übergeben:> #define SET_PIN(port, pin) (port) |= (1 << (pin));> #define PIN_LED (PORTA, PA0)> /* ... some code ... */> SET_PIN(PIN_LED)> /* ... some code ... */> dieses schlägt jedoch fehl, da an das Makro nur ein (anstatt zwei)> Parameter übergeben wird. Anscheinend wird SET_PIN vor PIN_LED> substituiert.
Hast du mal die Reihenfolge geändert?
Oliver S. schrieb:
> Am Rande: ich möchte dieses Funktionalität bewusst mit Makros (und nicht> Funktionen) implementieren. Ein "Inlinen" der Funktion hat nicht immer> zum gewünschten Resultat geführt, manchmal scheint der Compiler trotzdem> einen Funktionsaufruf einzufügen.
Wenn sonst alles gleich bleibt, sollte die Optimierung -Os
Funktionsaufrufe produzieren, im Gegensatz zu -O2.
Wenn die Funktion ohne "static" deklariert ist, muss sie als echte
Funktion existieren. Dann wäre es ja Flash-Verschwendung, sie nochmal
inline ein zu bauen. Und dann wieder, wenn wirklich auf Geschwindigkeit
optimiert wird und die Funktion nur 3 Befehle enthält...
Schaulus Tiger schrieb:>> Am Rande: ich möchte dieses Funktionalität bewusst mit Makros (und nicht>> Funktionen) implementieren. Ein "Inlinen" der Funktion hat nicht immer>> zum gewünschten Resultat geführt,
In GCC kann mit dem Attribut always_inline zusätzlich zu inline das
Inlining erzwingen.
> Wenn sonst alles gleich bleibt, sollte die Optimierung -Os> Funktionsaufrufe produzieren, im Gegensatz zu -O2.
Die Entscheidung, ob inlined wird oder nicht, wird zwar von der Art der
Optimierung beeinflusst, ist aber komplexer als dieses simple Schema.
das Funktionsattribut _flatten_ bringt gcc dazu, in die betreffende
Funkion soviel wie möglich per inline "reinzuziehen". Unabhängig davon,
ob die aufgerufenen Funktionen selbst inline deklariert sind und auch
(zumindest bei meinen Versuchen, dokumentiert ist das m.W. nicht)
unabhängig von der Optimierung.
Natürlich muß der entsprechende Code von der Funktion aus sichtbar sein.
Damit kann man auch in per -Os übersetzten Modulen einzelne Funktionen
gezielt "schnell" machen.
> dieses schlägt jedoch fehl, da an das Makro nur ein (anstatt zwei)> Parameter übergeben wird. Anscheinend wird SET_PIN vor PIN_LED> substituiert.
Nein, Der Präprozessor substituiert PIN_LED inklusive Klammern!
Was ist an Funktionen eigentlich so schlimm, dass man sich sowas bauen
muss? Ein gefühltes diffuses Optimierungsbedürfnis? Fricklerstolz und
Mittelfinger gegen die abgehobenen Richtig-und-schön-Programmierer?
Tom schrieb:> Was ist an Funktionen eigentlich so schlimm, dass man sich sowas bauen> muss?
Nichts, ausser ein bisschen Performance falls der Compiler kein inline
unterstützt. Es gibt sogar Coding Standards die der Benutzung solcher
Makros mit Parametern (Function-like macros) unterbinden - z.B. MISRA C.