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
staticinlineboolEndPosition(void){
4
return(bool)PINA&(1<<0);//PINA0 - End position switch
5
6
//Lösung B:
7
staticinlineuint8_tEndPosition(void){
8
returnPINA&(1<<0);//PINA0 - End position switch
9
}
10
11
intmain()
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
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
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
staticinlineboolEndPosition(void){
2
return0!=(PINA&(1<<3));//PINA3 - End position Switch
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.
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.
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 ;-)
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 ;-)
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.
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
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.
Eine eigene Frage?
Dieser Thread ist über 8 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.