Forum: Mikrocontroller und Digitale Elektronik C-> Rückgabewerte?!


von Jenny A. (Gast)


Lesenswert?

Halli Hallo (:

Was genau bewirkt die Abfrage in der "return" Anweisung?
Was wird denn im Endeffekt zurückgegeben?
1
uint8_t PICC_IsNewCardPresent() 
2
{
3
  byte bufferATQA[2];
4
  byte bufferSize = sizeof(bufferATQA);
5
6
  // Reset ModWidthReg
7
  RFIDWrite(ModWidthReg, 0x26 );
8
9
  StatusCode result = PICC_RequestA( bufferATQA, &bufferSize );
10
  return (result == STATUS_OK || result == STATUS_COLLISION);
11
}

von Daniel (Gast)


Lesenswert?

Servus,

Entweder true oder false.

True wenn der Status STATUS_OK ODER STATUS COLLISION ist.
False wenn der Status ein anderer ist.

von Sebastian R. (sebastian_r569)


Lesenswert?

Wenn result entweder STATUS_OK oder STATUS_COLLISION (sind defines) ist, 
wird 1 zurückgegeben. Wenn ein anderer Status als "ok" oder "collision" 
in result steht, wird eine 0 zurückgegeben.

von Bernd K. (prof7bit)


Lesenswert?

Der Ausdruck wertet zu bool aus, dann wird er aber implizit in ein 
uint8_t gecastet weil die Funktion so deklariert ist. Letzteres finde 
ich unschön, der Rückgabewert einer Funktion sollte als das deklariert 
sein was er eigentlich ist, in diesem Falle bool.

Viele C-Programmierer haben damit kein Problem weil sie diese 
Schlampigkeit schon immer so gewohnt waren, ich jedoch der mit Pascal 
aufgewachsen ist habe dazu jedoch eine wesentlich strengere Einstellung 
und ich bin der festen Überzeugung daß es hilfreich ist möglichst 
penibel auf die Wahl seiner seiner Datentypen zu achten, schon allein 
der Lesbarkeit und Dokumentation zuliebe, selbst wenn der Compiler es 
ignoriert.

: Bearbeitet durch User
von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

Bernd K. schrieb:
> Letzteres finde
> ich unschön, der Rückgabewert einer Funktion sollte als das deklariert
> sein was er eigentlich ist, in diesem Falle bool.

Tut es doch. Der == Operator liefert wie Sebastian bereits schrieb 0 
oder 1 als Integer. C kennt nativ erstmal keinen Boolean Typ, siehe 
auch:

https://stackoverflow.com/questions/1921539/using-boolean-values-in-c

von Yalu X. (yalu) (Moderator)


Lesenswert?

Tobias B. schrieb:
> C kennt nativ erstmal keinen Boolean Typ

C kannte keinen Bool-Typ, das wurde aber vor 20 Jahren geändert. Aus
Kompatibilitätsgründen liefern die logische Operatoren &&, || und !
immer noch int als Ergebnis.

von Wilhelm M. (wimalopaan)


Lesenswert?

Man könnte / sollte das als C++ ansehen:

Jenny A. schrieb:
> uint8_t PICC_IsNewCardPresent()
> {
>   byte bufferATQA[2];
>   byte bufferSize = sizeof(bufferATQA);
>
>   // Reset ModWidthReg
>   RFIDWrite(ModWidthReg, 0x26 );
>
>   StatusCode result = PICC_RequestA( bufferATQA, &bufferSize );
>   return (result == STATUS_OK || result == STATUS_COLLISION);
> }

Denn die Deklaration
1
uint8_t PICC_IsNewCardPresent();

hieße ja in C eine Funktion mit beliebiger Parameterliste, und in C++ 
eine Funktion mit leerer Parameterliste.
Es sei denn, es ist C2x-Code.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Denn die Deklaration uint8_t PICC_IsNewCardPresent();
>
> hieße ja in C eine Funktion mit beliebiger Parameterliste, und in C++
> eine Funktion mit leerer Parameterliste.

Vermutlich hat der/die TO einfach nur das Schlüsselwort "void" 
vergessen.

> Es sei denn, es ist C2x-Code.

Im Betreff steht "C".

: Bearbeitet durch Moderator
von Wilhelm M. (wimalopaan)


Lesenswert?

Frank M. schrieb:
> Vermutlich hat der/die TO einfach nur das Schlüsselwort "void"
> vergessen.

Genau das vermute ich auch, und wollte darauf hinweisen. Bzw. vielen ist 
das einfach gar nicht bewusst, wie auch der Typ int der logischen oder 
relationalen Operatoren und der impliziten Konvertierung von int -> 
bool.

von Stefan F. (Gast)


Lesenswert?

Das "void" bei leeren Parameterlisten ist schon laaaaange optional. Ich 
kann mich gar nicht mehr daran erinnern, es jemals hingeschrieben zu 
haben.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Frank M. schrieb:
>> Es sei denn, es ist C2x-Code.
>
> Im Betreff steht "C".

Auch C2x ist C bzw. wird es sein. Dort sollen die K&R-Parameterlisten
abgeschafft werden, so dass dann

1
void func() {

gleichbedeutend ist mit

1
void func(void) {

Darauf wollte Wilhelm wohl hinaus.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Bzw. vielen ist das einfach gar nicht bewusst,

Vielen sind auch die möglichen Compiler-Switches nicht bewusst. Ein

   -Wstrict-prototypes

hätte den Fehler direkt aufgedeckt.

Generell empfiehlt sich immer, mindestens die Optionen

    -Wall -Wextra -Wstrict-prototypes -Werror

anzuwenden. Sicher gibt es da noch ein paar mehr. Aber nicht alle 
Optionen zu Warnungen sind immer sinnvoll.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Stefan F. schrieb:
> Das "void" bei leeren Parameterlisten ist schon laaaaange optional.

Wenn man es aber weglässt, wird daraus eine K&R-Deklaration, d.h. Anzahl
und Typ der Parameter sind unbestimmt. Beispiel:

1
void func1();
2
void func2(void);
3
4
main(void) {
5
  func1(1, 2, 3); // in C18 korrekt (keine Typprüfung), in C2x und C++ Fehler
6
  func2(1, 2, 3); // Fehler
7
}

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Stefan F. schrieb:
> Das "void" bei leeren Parameterlisten ist schon laaaaange optional. Ich
> kann mich gar nicht mehr daran erinnern, es jemals hingeschrieben zu
> haben.

Bei C++ ist das "void" tatsächlich optional.

Aber Vorsicht:

Bei C bedeutet eine Deklaration einer Funktion mit leerer 
Parameterliste: "Ich weiß nicht, ob die Funktion Parameter benötigt oder 
nicht."

So kann man schreiben:
action.c:
1
int action (char * str)
2
{
3
    printf ("%s\n", str);
4
    return 0;
5
}

action.h:
1
int action ();

Und dann in main.c:
1
#include "action.h"
2
...
3
    action ();

Das geht anstandslos durch den C-Compiler, wenn man es nicht explizit 
verbietet (z.B. beim gcc mit -Wstrict-prototypes).

Folge: Das Programm wird compiliert, crasht dann aber beim Aufruf.

Grund: Vor ANSI-C kannte C überhaupt keine Prototypes. Da wurden 
Funktionen immer mit leeren Parameterlisten deklariert - egal ob sie 
welche benutzten oder nicht.

Ich sehe das alt Altlast, die in diesem Jahrtausend besser über Bord 
gekippt werden sollte.

: Bearbeitet durch Moderator
von Bernd K. (prof7bit)


Lesenswert?

Tobias B. schrieb:
> Tut es doch. Der == Operator liefert wie Sebastian bereits schrieb 0
> oder 1 als Integer

Das ist es doch was ich meinte, auch wenn es für den Compiler das selbe 
ist wie ein int oder aus irgendwelchen Legacy-Gründen ein int geliefert 
wird obwohl eigentlich von der Intention her ein bool gemeint und 
gewollt ist kann man doch auch bool hinschreiben um dem Leser klar zu 
machen daß diese Funktion tatsächlich nur wahr oder falsch liefert und 
eben keine beliebige Integerzahl. Das sind subtile Feinheiten (es gibt 
noch mehr davon in vielen Bereichen) die in Summe den ganzen Code 
angenehmer zu lesen machen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Bernd K. schrieb:
> Das ist es doch was ich meinte, auch wenn es für den Compiler das selbe
> ist wie ein int oder aus irgendwelchen Legacy-Gründen ein int geliefert
> wird obwohl eigentlich von der Intention her ein bool gemeint und
> gewollt ist kann man doch auch bool hinschreiben um dem Leser klar zu
> machen daß diese Funktion tatsächlich nur wahr oder falsch liefert und
> eben keine beliebige Integerzahl.

Genau! -> "Stop using C" [Kate Gregory] Und wer diesen Vortrag gehört 
hat, versteht vllt jetzt, was er sagen will. Man könnte auch für den 
Title "Stop using the C-habit in C++ or C" wählen.

von Stefan F. (Gast)


Lesenswert?

Frank M. schrieb:
> Aber Vorsicht:

Danke Frank, das wusste ich noch nicht. Lässt sich leicht 
nachvollziehen, wenn man weiß, wonach man sucht.

von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Auch C2x ist C bzw. wird es sein. Dort sollen die K&R-Parameterlisten
> abgeschafft werden, so dass dann
>
> void func() {
>
> gleichbedeutend ist mit
>
> void func(void) {
>
> Darauf wollte Wilhelm wohl hinaus.

Genau!
Meistens schreibe ich zwar C++ oder C++17/C++2a, aber hier meinte ich
tatsächlich C2x, also den kommenden C-Standard, in dem dann foo(void) 
äquivalent zu foo() wird.

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.