C-> Rückgabewerte?!

Gast #6069904
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
}
#6069922
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.
(Firma: www.elpra.de) Persönliche Seite #6069929
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
#6069944
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.
Gast #6069967
Das "void" bei leeren Parameterlisten ist schon laaaaange optional. Ich 
kann mich gar nicht mehr daran erinnern, es jemals hingeschrieben zu 
haben.
Moderator Persönliche Seite #6069980
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.
Moderator #6069989
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
}
Moderator Persönliche Seite #6069992
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.
#6069999
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.
#6070005
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.
#6070036
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.