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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Jan (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


Bewertung
-3 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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


Bewertung
2 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
-2 lesenswert
nicht 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)


Bewertung
1 lesenswert
nicht 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)


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

von Jan (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht 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)


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

Ok ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.