Forum: Mikrocontroller und Digitale Elektronik return von Funktion


von Frank (Gast)


Lesenswert?

Hallo,
ich habe eine Funktion. jetzt möchte ich kontrollieren, ob die Funktion 
ausgeführt wurde.

[code]
int main(void){
  ...
  if(function()){
    ...
  }
  else{
    ...
  }
  ...
}



void function(void){
  ...
  return
}


jetzt bekomme ich die Fehlermeldung
void value not ignored as it ought to be
ist es möglich direkt in einer if-Bedingung eine Funktion auszuführen 
und dadurch zu kontrollieren, ob diese richtig ausgeführt wurde?

Frank

von Michael M. (eos400dman)


Lesenswert?

Ja das geht. Mach den Rückgabewert der Funktion zu einer Zahl und lass 
sie 0 zurück geben wenn alles i.O. ist und 1 sonst. Dann fragst du im if 
auf gleich 0 ab.

Viele Grüße Michael

von dunno.. (Gast)


Lesenswert?

Michael M. schrieb:
> lass
> sie 0 zurück geben wenn alles i.O. ist und 1 sonst.

noch besser: du führst defines ein für Fehlercodes.
das macht das ganze lesbar, und ermöglicht dir eine übersichtliche 
Fehlerbehandlung, etwa so:
1
#define SUCCESS 0
2
#define PROBLEM_1 1
3
4
if((returncode = funktion()) != SUCCESS)
5
{
6
  switch(returncode)
7
  { 
8
    case PROBLEM_1:
9
      behebeProblem();
10
      break;
11
12
    default:
13
      ohje();
14
      break;
15
  }
16
}

von Peter D. (peda)


Lesenswert?

Michael M. schrieb:
> lass
> sie 0 zurück geben wenn alles i.O. ist und 1 sonst.

Leider gibt es dafür keinen Standard.
Z.B. getchar() liefert 0..255 für o.k. (das empfangene Zeichen) bzw. -1, 
-2 für Fehler (Timeout, Frame-Error, usw.).

von TX (Gast)


Lesenswert?

Frank schrieb:
> void function(void){
>   ...
>   return
> }

Eine "void" Funktion kann nix zurückgeben. Du musst den Rücgabetyp 
definieren, z.b. als unsigned char:

unsigned char (void)
{
     return 1;
}

von Meret Wenger (Gast)


Lesenswert?

Dein Problem ist:
1
void function(void)

Dort musst du den Typ deines Rückgabeparameters angeben.

z.B.
1
int function(void)

in der Funktion selbst musst du dann aber auch etwas zurück geben.
In deinem Fall wäre es
1
//fnc ok
2
return 1;
3
//fnc nok
4
return 0;

von Frank (Gast)


Lesenswert?

oh ja, jetzt funktioniert es

von fop (Gast)


Lesenswert?

Hallo,
erstmal ist klar Deine Funktion gibt nichts zurück, was ein if abtesten 
könnte. Das will Dir die Fehlermeldung sagen.
Aber Deine Frage war ja auch, dass Du abfragen willst, ob die Funktion 
durchlaufen wird. Und genau da ist ein Aufruf als Teil einer Bedingung 
oder einer Berechnung kontraproduktiv. In der ganz einfachen Form wie in 
Deinem Beispiel mag das noch gut gehen, aber schon ein
1
if ((42 == bla()) || (23 == blupp()))
2
{
3
    aha++;
4
}
ist nicht zu überblicken. Denn schon ein Aufruf der Funktion bla() 
reicht aus und alles könnte klar sein, gibt sie 42 zurück muss 
inkrementiert werden egal was blupp() zurück geben würde. Also spart 
sich der vom Compiler erzeugte Code u.U. den Aufruf von blupp(). Das ist 
jedoch noch nicht Alles. Einem C-Compiler steht es frei, wie er Deinen 
Ausdruck abarbeitet. Wenn er meint zuerst blupp() aufzurufen, um dann zu 
entscheiden, ob bla() überhaupt aufgerrufen wird, dann ist das so, 
basta. Und wenn er sich doof anstellt ruft der vom Compiler erstellte 
Code immer beide Funktionen auf. In welcher Reihenfolge ist dann auch 
wieder sein Bier. Um das ganze noch richtig auf die Spitze zu treiben : 
das kann sich ändern, wenn mann die Einstellungen zur Optimierung 
ändert, den Compiler updatet oder ganz wechselt.
Wenn also diese Funktionen Nebeneffekte haben, sprich etwas machen 
sollen ausser einem Zahlenwert zu ermitteln, der dann abgetestet wird 
verkneife es Dir unbedingt den Funktionsaufruf in eine Bedingung oder 
Berechnung zu setzen.
Ausgaben in beiden Funktionen z.B. : wenn manchmal die Hälfte fehlt 
(weil die Funktion nicht aufgerufen wird) oder die Reihenfolge sich 
umdreht.
Ein quasi Klassiker : bla() verändert globale Variablen, auf die auch 
blupp() zugreift.
Da kennt sofort jeder Deinen Namen, der den Code um ein winziges Feature 
ergänzen soll.
Aber zur Frage zurück, wird meine Funktion ausgeführt. Wenn Du die 
Antwort nur beim Erstellen der Software wissen willst, um einen Fehler 
einzugrenzen, haben sich bei Mikrokontrollern unbenutzte Portpins 
bewährt, die man auf Ausgang schaltet und dann entweder bei jedem 
Eintritt in die Funktion toggelt oder beim Einsprung setzt und beim 
Verlassen zurück setzt.
Das lässt sich dann mit einem Oszilloskop super nachvollziehen. Oft auch 
der Moment, ab dem die Funktion schlagartig nicht mehr aufgerufen wird.
Geht es um Funktionen, die auch im Normalbetrieb der Software 
fehlschlagen können und diesen Zustand melden sollen, bleibt unter c 
eigentlich nur der Rückgabewert. Also so etwas wie Zugriff auf eine 
Datei beim PC als Beispiel.
Wie aber schon zu Beginn lang und breit erläutert, solltest Du dann zum 
Aufruf der Funktion, diesen Wert einer Variable zuweisen und die 
Variable mit if abfragen.
Sollte jeamnd Deinen Quellcode zu Gesicht bekommen, für den mehrer 
return-Anweisungen pro Funktion genauso pfui sind wie goto-Anweisungen, 
solltest Du in der Funktion eine Variable mit dem vorgesehenen 
Rückgabewert anlegen. Evtl. initialisierst Du sie mit dem Wert für 
Fehler und überschreibst diesen erst wenn alles geklappt hat. Wenn Du 
magst, kannst Du noch verschiedene Werte für verschiedene Fehler 
benutzen und Dich bei der Gelegenheit mit #defines oder einem enum 
austoben, damit man beim Lesen des Quelltextes ahnen kann, was die Werte 
bedeuten. Und zum Schluss wird die Variable mit return zurück gegeben. 
Aber bitte keine lokale Variable als Array von Buchstaben anlegen, da 
eine Fehlermeldung im Klartext rein schreiben und einen Zeiger auf das 
Array zurück geben. Da lauert nämlich der nächste Schuss in's Knie : das 
Array ist nach Ende der Funktion tot. Und ein Zeiger, der gerade noch 
darauf zeigte, führt damit genau genommen in die Irre.

von Yalu X. (yalu) (Moderator)


Lesenswert?

fop schrieb:
> Einem C-Compiler steht es frei, wie er Deinen
> Ausdruck abarbeitet. Wenn er meint zuerst blupp() aufzurufen, um dann zu
> entscheiden, ob bla() überhaupt aufgerrufen wird, dann ist das so,
> basta. Und wenn er sich doof anstellt ruft der vom Compiler erstellte
> Code immer beide Funktionen auf. In welcher Reihenfolge ist dann auch
> wieder sein Bier. Um das ganze noch richtig auf die Spitze zu treiben :
> das kann sich ändern, wenn mann die Einstellungen zur Optimierung
> ändert, den Compiler updatet oder ganz wechselt.

Nein.

Ob, und in welcher Reihenfolge die Operanden von || ausgewertet werden,
ist ganz klar im Standard definiert. Da hat der Compiler keinen
Spielraum.

von Dr. Zeh (Gast)


Lesenswert?

fop schrieb:
> jedoch noch nicht Alles. Einem C-Compiler steht es frei, wie er Deinen
> Ausdruck abarbeitet. Wenn er meint zuerst blupp() aufzurufen, um dann zu
> entscheiden, ob bla() überhaupt aufgerrufen wird, dann ist das so,
> basta. Und wenn er sich doof anstellt ruft der vom Compiler erstellte
> Code immer beide Funktionen auf.

Das ist nicht richtig. Sowohl die "Short Circuit Evaluation" als auch 
die Reihenfolge der Auswertung sind im C-Standard festgelegt.

6.5.13, logical AND operator:
(4). Unlike the bitwise binary & operator, the && operator guarantees 
left-to-right evaluation; there is a sequence point after the evaluation 
of the first operand. If the first operand compares equal to 0, the 
second operand is not evaluated.

6.5.14, logical OR operator:
(4) Unlike the bitwise | operator, the || operator guarantees 
left-to-right evaluation; there is a sequence point after the evaluation 
of the first operand. If the first operand compares unequal to 0, the 
second operand is not evaluated.

Gilt auch für C++.

> In welcher Reihenfolge ist dann auch wieder sein Bier. Um das ganze noch
> richtig auf die Spitze zu treiben : das kann sich ändern, wenn mann die
> Einstellungen zur Optimierung ändert, den Compiler updatet oder ganz
> wechselt.

3 x nein. Und wenn doch, ist es ein Bug.

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.