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
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
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:
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.).
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;
}
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.
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.
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.