Forum: Mikrocontroller und Digitale Elektronik Besser bool oder uint8_t für binäre Statusinformation ?


von Jan (Gast)


Lesenswert?

Hallo Mikrocontrollergemeinde,

Ich programmiere MCUs in C und habe mir schon oft folgende Frage 
gestellt :

Ist es besser bool zu benutzen,  oder uint8_t um binäre 
Statusinformation zu Speichern oder Zurückzugeben? (Siehe kleines 
Beispiel)

1
 
2
//Lösung A: 
3
static inline bool EndPosition (void){
4
  return (bool)PINA&(1<<0);    //PINA0 - End position switch
5
6
//Lösung B:
7
static inline uint8_t EndPosition (void){
8
  return PINA&(1<<0);    //PINA0 - End position switch
9
}
10
11
int main()
12
{
13
  .
14
  ...
15
  while(!EndPosition)
16
  {
17
  StepperDrive();
18
  };
19
  
20
  ..
21
  .


Welches ist zu bevorzugen ?
Lösung A oder Lösung B ?

Ich vermute beides erzeugt den gleichen Maschinencode (Ich habe es aber 
nicht geprüft).
Gibt es Aspekte unter welchen Lösung A oder Lösung B besser ist?
Oder ist es wirklich egal?

Grüße und Danke im Voraus für Eure Antworten.

Jan

von Arno (Gast)


Lesenswert?

Ich finde Lösung 1 schöner, weil zum einen der Quelltext mehr 
Informationen enthält, zum anderen weil für bool (soweit ich weiß) gilt: 
!!a == a. Für uint8_t gilt das nicht immer.

MfG, Arno

von achs (Gast)


Lesenswert?

bool ist normalerweise vom typ int. und dieser Typ ist in c für diesen 
Prozessor der Default-Typ, in der Regel der schnellste.

Bei einem reinen 8-Bitter könnte bool jedoch Performance kosten.
Zudem kann 16 oder 32 Bit für eine binäre Info RAM kosten.

Dein Code ist zwar richtig (die Funktionen liefern 0 oder 1 zurück), der 
Quelltext sagt aber, dass es nur zufällig so ist.

Hättest Du ein Höherwertiges Bit getestet, so wäre der Rückgabewert 2, 4 
oder was auch immer. Das ist auch OK, nur ist der Rückgabewert dann 
strenggenommen nicht bool (0/1), sondern 0/!=0.
1
static inline bool EndPosition (void){
2
  return 0!=(PINA&(1<<3));    //PINA3 - End position Switch
3
}
oder einfach doppelt negieren
1
static inline bool EndPosition (void){
2
  return !!(PINA&(1<<3)); 
3
}

von Mikro 7. (mikro77)


Lesenswert?

Jan schrieb:
>
1
>   return (bool)PINA&(1<<0);    //PINA0 - End position switch
2
>

Wenn schon boolean, warum dann nicht
1
return 0 != (PINA&(1<<0)) ;

von Peter D. (peda)


Lesenswert?

bool ist schöner, da es ein Leser besser verstehen kann.
Als Inline ergibt sich kein größerer Code.
Als echte Funktion entsteht ein kleiner Overhead durch die Umwandlung 
von alles !0 in 1.

von Til S. (Firma: SEGGER) (til_s)


Lesenswert?

Lösung C wenn es um Effizienz geht ;-)

Bei den meisten Calling Conventions wird der Return Wert einer Funktion 
in einem CPU Register zurückgegeben. Am effizientesten ist es, wenn die 
Variablenbreite des Return Wertes der Breite des Registers entspricht.

Also sagen wir du hast eine 8 Bit CPU mit 8 Bit breiten Registern und 
möchtest eine long zurückgeben. Das passt dann nicht mehr in ein 
Register, also ineffizient. Genauso wenn du eine 32 Bit CPU hast und 
einen 8 Bit Wert zurückgeben möchtest. Das passt zwar rein aber 
anschließend muss evtl. noch maskiert werden.
Bei den meisten CPU/Compiler Kombinationen entspricht der "int" Datentyp 
der CPU Registerbreite. Das gilt aber natürlich nur für 16/32 Bit CPUs. 
Bei einer 8 Bit CPU würdest du "char" nehmen. Aber Vorsicht, auch hier 
gibt es Ausnahmen, ich erinnere mich an den Renesas H8 und den Renesas 
Compiler. Der H8 ist eine 32 Bit CPU ist, aber ein "int" war nur 16 Bit 
groß.

Bei dir müsstest du schauen, wie bool implementiert ist. Es kann sein, 
dass es das gleiche wie uint8_t ist. Dann würde ich bool nehmen, wenn 
die Funktion eine true/false Wert zurückliefert und nicht einen Wert 
zwischen 0..255. Ich würde die Funktion dann aber auch 
IsEndPositionReached() oder so nennen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

achs schrieb:
> bool ist normalerweise vom typ int.

Bei GCC ist es üblicherweise _Bool, und der ist 1 Byte groß (zumindest 
für: avr, arm, x86, x86_64).

von m.n. (Gast)


Lesenswert?

Til S. schrieb:
> ich erinnere mich an den Renesas H8 und den Renesas
> Compiler. Der H8 ist eine 32 Bit CPU ist, aber ein "int" war nur 16 Bit
> groß.

Beim IAR Compiler waren (sind?) es 32 Bit ;-)

von Volker S. (vloki)


Lesenswert?

Warum nicht einfach:
#define EndPosition PINA0

oder im Allgemeinen Bitfelder zum Speichern von binären Informationen?

Als Rückgabewert einer Funktion vielleicht aber doch bool,
wenn der Compiler das überhaupt unterstüzt ;-)

: Bearbeitet durch User
von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Jan schrieb:
> Welches ist zu bevorzugen ?
> Lösung A oder Lösung B ?

A

> Gibt es Aspekte unter welchen Lösung A oder Lösung B besser ist?

Lesbarkeit, Robustheit, Ausdruck von Intention.

von Peter (Gast)


Lesenswert?

Ich würde "bool" bevorzugen, da die Intention des Programmierers 
eindeutiger und das Programm somit lesbarer ist.

von Jan (Gast)


Lesenswert?

Vielen Dank für die Zahlreichen Antworten.

Ich denke auch A ist die bessere Variante.
Vielleicht könnte man verallgemeinern das der gewählte Variablentyp 
immer dem Datentyp entsprechen sollte.
In diesem Fall möchte man einen „true“ oder „false“ zurückgeben, also 
ist bool die Richtige Wahl.

Til S. schrieb:
> Lösung C wenn es um Effizienz geht ;-)

Ist es tatsächlich so, dass die Lösung A unter Umständen nicht die 
effizienteste Lösung ist?
(Bei Verwendung moderner C-compiler.)
Ich dachte das durch das inlinen,  Lösung A immer die effizienteste 
Variante ist.

Volker SK schrieb :
> Warum nicht einfach:
> #define EndPosition PINA0

Funktionen sind Makros vorzuziehen.
Bei Makrofunktionen geht die Type-überprüfung verloren.


Gruss,
Jan

von beric (Gast)


Lesenswert?

Lösung C ;-)
1
typedef enum {
2
  UNBEKANNT, AM_ENDE, UNTERWEGS
3
} Position;
4
5
Position wo_bin_ich(void)
6
{
7
  Position pos = UNBEKANNT;
8
9
  if(PINA&(1<<0)
10
    pos = UNTERWEGS;
11
  else if ...
12
    pos = AM_ENDE;
13
  
14
  return pos;
15
}
16
17
main()
18
{
19
  ...
20
  if(wo_bin_ich() == UNTERWEGS)
21
  {
22
     Stepper();
23
  }
24
  ...
25
}

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jan schrieb:
> In diesem Fall möchte man einen „true“ oder „false“ zurückgeben,
> also ist bool die Richtige Wahl.

Naja, eigentlich will man zurückgeben, ob PINA.0 "low" oder "high" 
ist. Du gibst aber tatsächlich zurück "PINA.0 == high" :-)

Was gewollt ist, hängt von der Anwendung ab.

von Volker S. (vloki)


Lesenswert?

Jan schrieb:
> Funktionen sind Makros vorzuziehen.
> Bei Makrofunktionen geht die Type-überprüfung verloren.

Ok ;-)

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.