Wie viel "freier" Code im Programm?

Gast #3031559
Lesenswert?

Was meint ihr, sollte man jeden Codeschnippsel, sei es eine Zeile oder 
Befehl, in eine Funktion packen?

Zum Bsp.
1
 ToggleLed();
Anstatt
1
Portx ^= (1<<LED_PIN);
Wobei Zweiteres der Inhalt der Funktion darstellt. Was gehört zum "Guten 
Ton"?
Geschwindigkeit sollte das selbe sein, der Compiler wird sowas wohl 
sowieso inlinen.


Ingo
Gast #3031575
Lesenswert?

Ingo schrieb:
> Was meint ihr, sollte man jeden Codeschnippsel, sei es eine Zeile oder
> Befehl, in eine Funktion packen?
wenn dieser Schnipsel oft (ab 3x ;-) ) vorkommt und sich die 
theoretische Möglichkeit ergibt, diesen eventuell mal ändern zu wollen 
(zB weil man die LED an einen anderen Pin hängen will) - Ja.
Um sicherzustellen dass das tatsächlich inlined wird kann man noch ein 
"inline" an die Funktionsdeklaration dranschreiben.
#3031578
Lesenswert?

Weder, noch.

Profis (wie ich ;-)) würden das so machen:
1
union blabla {
2
  int i16bit;
3
  struct {
4
        unsigned led1:1;
5
        unsigned led2:1;
6
        unsigned led3:1;
7
        unsigned reserved:13;
8
    } bits;
9
};
10

11

12
blabla* LEDport = 0xadressevonport;
13

14

15

16
und dann im Code:
17

18
LEDport.bits.led1 ^=1;
Gast #3031618
Lesenswert?

> Profis (wie ich ;-)) würden das so machen:

Vorausgesetzt, der Port ist überhaupt über Speicheradressen ansprechbar 
und benötigt nicht spezielle Instruktionen wie IN und OUT.

> Geschwindigkeit sollte das selbe sein, der Compiler wird sowas wohl
> sowieso inlinen.

Na ja, besser nicht bei space optimierung statt speed optimierung.

Man sollte prinzipell nichts doppelt schreiben, weil man es dann doppelt 
ändern muß.

In Assembler lohnt sich eine Funktion für deine Anweisungen schon wenn 
sie nur 2 mal verwendet wird, in Hochsprachen ist es manchmal 
zweifelhaft aber was kann der Programmierer für schlechte Kompiler.

Aber wenn sie nur ein mal aufgerufen wird, ist eine Funktion (auch wenn 
sie ge-inline-t wird) eher blöd: Man muß sie suchen (denn aus TogglePort 
geht nun wirklich nicht hervor welches) und im Quelltext vom Lesefluss 
weg woanders hin springen
#3031619
Lesenswert?

Claus M. schrieb:
> Profis (wie ich ;-)) würden das so machen:
Du bist ja sogar ein doppelter Profi. 16-Bit-Integer, um einen 
8-Bit-Port zu beschreiben. Respekt.

1
#define LED_PORT PORTA
2
#define LED_TOGGLE PINA
3
#define LED_0 3
4

5
PORTA ^= (1 << LED_0);
6
     wird zu:
7
     43e:  82 b1         in  r24, 0x02  ; 2
8
     440:  98 e0         ldi  r25, 0x08  ; 8
9
     442:  89 27         eor  r24, r25
10
     444:  82 b9         out  0x02, r24  ; 2
11

12
LED_TOGGLE |= (1 << LED_0);
13
     wird zu:
14
     43e:  03 9a         sbi  0x00, 3  ; 0
15

16
LED_PORT |= (1 << LED_0);
17
     wird zu:
18
     43e:  13 9a         sbi  0x02, 3  ; 2
19

20
LED_PORT &= ~(1 << LED_0);
21
     wird zu:
22
     43e:  13 98         cbi  0x02, 3  ; 2
Jetzt rate mal, wie Profis das machen...

mfg.
#3031630
Lesenswert?

Thomas Eckmann schrieb:
> Du bist ja sogar ein doppelter Profi. 16-Bit-Integer, um einen
>
> 8-Bit-Port zu beschreiben. Respekt.

Mit 8-Bit Hobbybastler-uC gebe ich mich halt normalerweise nicht ab ;-). 
Außerdem ging es um das Prinzip.


>Autor: Simon K. (simon) schrieb:
>Gegenfrage: Wo schreibst du mit der Union in den Speicher? Nirgendwo.
>Du benutzt also ein unbekanntes Speicherlayout der Union um Sachen aus
>dem Speicher zu lesen.

Ich glaube du hast es einfach immer noch nicht kapiert.
Gast #3031643
Lesenswert?

Ingo schrieb:
> Was meint ihr, sollte man jeden Codeschnippsel, sei es eine Zeile oder
> Befehl, in eine Funktion packen?

Nein. Nicht jeden.

Ob man das macht oder nicht, kommt auf die näheren Umstände an. 
Allgemein kann man jedoch sagen, daß ein zu heftiges Zerpflücken der 
Gesamtfunktion in Minischnipsel nicht gut ist, weil zu unleserlich und 
oft auch zu uneffektvem Code führt. Also mache lieber Funktionen von 
sinnvollem Umfang, weder Mammutfunktionen noch 1000 Minischnipsel.

W.S.
Gast #3031671
Lesenswert?

Claus M. schrieb:
> union blabla {
>   int i16bit;
>   struct {
>         unsigned led1:1;
>         unsigned led2:1;
>         unsigned led3:1;
>         unsigned reserved:13;
>     } bits;
> };

Kommt mir bekannt vor. In den PIC24 Headerfiles von Microchip findet 
man:
1
extern volatile unsigned int  LATA __attribute__((__sfr__));
2
typedef struct tagLATABITS {
3
  unsigned LATA0:1;
4
  unsigned LATA1:1;
5
  unsigned LATA2:1;
6
  unsigned LATA3:1;
7
  unsigned LATA4:1;
8
  unsigned :2;
9
  unsigned LATA7:1;
10
} LATABITS;
11
extern volatile LATABITS LATAbits __attribute__((__sfr__));
und ich schreib dann noch dazu
1
#define LED1 LATAbits.LATA0
2
.
3
.
4
LED1 ^= 1;
und wenn die LED 1 an einen anderen Port kommt, wird nur das define 
geändert.

MfG Klaus

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