Forum: Mikrocontroller und Digitale Elektronik Was ist der Vorteil, wenn ich eine Funktion so definiere?


von amateur (Gast)


Lesenswert?

Was ist der Vorteil, wenn ich die Funktion so definiere und nicht wie 
gewohnt? Speicherplatz? Übersichtlichkeit?


#define PIN_SET_AS_PIO_OUTPUT(pin, pio) do { 
\
        Pio *pio_ptr; 
\
        if (PIO_A == pio) 
\
        { 
\
            pio_ptr = PIOA; 
\
        } 
\
        else if(PIO_B == pio) 
\
        { 
\
            pio_ptr = PIOB;                                      \
        } 
\
        else 
\
        { 
\
            pio_ptr = PIOC; 
\
        } 
\
        /* Bit corresponding to pin is set in output enable register. */ 
\
        pio_ptr->PIO_OER = pin; 
\
        /* PIO control is enabled on the specified pin. */ 
\
        pio_ptr->PIO_PER = pin; 
\
    } while (0);

von Matthias L. (Gast)


Lesenswert?

Das du dir jede Menge Ärger einhandeln kannst, ohne zu wissen warum.

Du definierst so keine Funktion, sondern ein Makro. Also eine reine 
Textersetzung.

Ich würde sowas nur für Konstanten nutzen.

von Ralf G. (ralg)


Lesenswert?

amateur schrieb:
> Was ist der Vorteil, wenn ich die Funktion so definiere und nicht wie
> gewohnt? Speicherplatz? Übersichtlichkeit?

Also, ich finde das Quatsch!
Wenn die Funktion nur einmal verwendet wird, könnte man sich dadurch den 
Code für den Aufruf sparen. Aber das erkennt der Compiler, glaube ich, 
auch selbst (inline-Funktion).

von sebastian (Gast)


Lesenswert?

Manche Sachen (z.B. Ports) kann man einer normalen Funktion nicht so 
einfach als Parameter übergeben. Vielleicht ist das hier der Fall.

von Karl H. (kbuchegg)


Lesenswert?

sebastian schrieb:
> Manche Sachen (z.B. Ports) kann man einer normalen Funktion nicht so
> einfach als Parameter übergeben. Vielleicht ist das hier der Fall.

Wenn du dir den Makrotext genauer ansiehst, siehst du, das eben genau 
dieser Fall hier nicht vorliegt. Durch dieses Makro hat man keinen 
Vorteil gegenüber einer inline Funktion. Aber dafür einige gravierende 
Nachteile.

von Kai S. (zigzeg)


Lesenswert?

Vorteil: Bessere Laufzeit-Performanz, da keine Sprungbefehle benoetigt 
werden.

Nachteile:
- Braucht mehr Programm-Speicher, da fuer jede Macro-Expansion eine 
Kopie der Funktion entsteht.
- Debugging wird nicht gut unterstuetzt (die ganze Funktion wird "in 
einer Zeile" ausgefuehrt)
- Compiler-Fehlermeldungen oft kryptisch

Fazit: Sowas hat man frueher mal gebraucht, als Compiler das inlining 
noch nicht so gut unterstuetzt haben. Heute sollte man sowas - ausser in 
ganz speziellen Faellen - besser vermeiden.

ZigZeg

von Karl H. (kbuchegg)


Lesenswert?

Kai S. schrieb:
> Vorteil: Bessere Laufzeit-Performanz, da keine Sprungbefehle benoetigt
> werden.

wir gehen schon davon aus, dass der Programmierer so intelligent ist, 
dem Compiler das inlinen zu ermöglichen.

> Nachteile:
> - Braucht mehr Programm-Speicher, da fuer jede Macro-Expansion eine
> Kopie der Funktion entsteht.
> - Debugging wird nicht gut unterstuetzt (die ganze Funktion wird "in
> einer Zeile" ausgefuehrt)
> - Compiler-Fehlermeldungen oft kryptisch

Den Hauptnachteil hast du vergessen
Verwende das Makro so

  PIN_SET_AS_PIO_OUTPUT( i++, PIO_A );

und erleb dein blaues Wunder. Das ist ein echtes Problem, dagegen sind 
die anderen 3 maximal Schönheitsfehler.

von B. L. (b8limer)


Lesenswert?

Matthias Lipinsky schrieb:
> Das du dir jede Menge Ärger einhandeln kannst, ohne zu wissen warum.
>
> Du definierst so keine Funktion, sondern ein Makro. Also eine reine
> Textersetzung.
>
> Ich würde sowas nur für Konstanten nutzen.

Ganz genau dafür ist es auch da. Und für nichts anderes. Schon garnicht 
für oberes Codebeispiel. Sowas lagert man wenn dann in einer Funktion 
aus.

#define ist eine TEXTERSETZUNG.

Verwendung z.B. pi:
1
#define pi 3,14159265
2
3
main(){
4
5
kreisflaeche = 2 * pi * r
6
7
}

ist für den Compiler genau das gleiche wie:
1
main(){
2
3
kreisflaeche = 2 * 3,14159265 * r
4
5
}

Speichertechnisch kein Vorteil, nur Übersichtlichkeit, Derivat aus ASM

von Bitte füllen Sie dieses Feld aus. (Gast)


Lesenswert?

B. Limer schrieb:
>
1
> #define pi 3,14159265
2
>
Wenn schon dann
1
#define pi 3.14159265
             ^

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Und schon da ginge es schief:
1
#define einsundeins 1+1
2
3
main() {
4
   int zwei = einsundeins;
5
   int waskommtdaraus   = zwei * 4;
6
   int waskommthierraus = einsundseins * 4;
7
}

von DerFremde (Gast)


Lesenswert?

Zumindest für den VS-Compiler führt ein
1
2 pi r

nicht zu einem 2 * 3,14159265 * r sondern zu 2 3,14159265 r.

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.