TRUE und FALSE im avr-gcc

Gast #1950108
Lesenswert?

Hallo Leute,

wie muß ich eine Funktion definieren, so dass ich sie im Hauptprogramm 
wie folgt abfragen kann? Ich habe das so probiert:
1
uint8_t wichtige_test_funktion(void)
2
{
3
  if (alles == ok)
4
   return 0;
5
  else
6
   return 1;
7
}

Und dann im Hauptprogramm:
1
if (!wichtige_test_funktion())
2
  usart_puts("Ganz großes Problem!\n\r");

Leider ist aber immer alles in Ordnung, ich komme nie zur Fehlermeldung, 
auch wenn ich sie provoziere?
Gast #1950120
Lesenswert?

Richard schrieb:
> Hallo Leute,
>
> wie muß ich eine Funktion definieren, so dass ich sie im Hauptprogramm
> wie folgt abfragen kann? Ich habe das so probiert:
> uint8_t wichtige_test_funktion(void)
> {
>   if (alles == ok)
>    return 0;
>   else
>    return 1;
> }

Warum gibst du 0 zurück, wenn alles Ok war? Und warum verwendest du 
nicht gleich bool?

> Und dann im Hauptprogramm:
> if (!wichtige_test_funktion())
>   usart_puts("Ganz großes Problem!\n\r");

Hier gibst du eine Fehlermeldung aus, wenn 0 zurückgegeben worden ist, 
also wenn alles ok war.
Moderator Persönliche Seite #1950315
Lesenswert?

So, wie in C99 beschrieben:
1
#include <stdbool.h>
2

3
bool wichtige_test_funktion(void)
4
{
5
  if (alles == ok)
6
   return false;
7
  else
8
   return true;
9
}

Es sind am Ende Aliase für 0 und 1.  Obwohl jeder Wert verschieden
von 0 als "wahr" interpretiert wird, liefern die Vergleichsoperatoren
in C ausschließlich diese beiden Werte.  Daher lässt sich dein
Beispiel auch wie folgt verkürzen:
1
bool wichtige_test_funktion(void)
2
{
3
  return !(alles == ok);
4
}
bzw.
1
bool wichtige_test_funktion(void)
2
{
3
  return alles != ok;
4
}

(womit auch offensichtlich wird, dass du irgendwie die Logik
vertauscht hast)
#1950444
Lesenswert?

Rolf Magnus schrieb:
> Richard schrieb:
>> Hallo Leute,
>>
>> wie muß ich eine Funktion definieren, so dass ich sie im Hauptprogramm
>> wie folgt abfragen kann? Ich habe das so probiert:
>> uint8_t wichtige_test_funktion(void)
>> {
>>   if (alles == ok)
>>    return 0;
>>   else
>>    return 1;
>> }
>
> Warum gibst du 0 zurück, wenn alles Ok war? Und warum verwendest du
> nicht gleich bool?

Es hat sich fast überall so eingebürgert dass wenn eine Funktion "0" 
zurückliefert, sie ohne Fehler durchgelaufen ist (für gewisse 
Schnittstellen/Funktionen ist es auch durch ANSI definiert, dass es so 
sein muss). Fehler werden meist mit Negativen Zahlen zurückgegeben. Bei 
manchen Funktionen macht es aber auch keinen Sinn z.B. bei file_exists.
ist z.B. bei strcmp genauso. Wenn der String gleich ist wird 0 
zurückgegeben. Wenn man also wissen will ob der String gleich war, 
schreibt man:
1
if(!strcmp(a,b))
2
  printf("String ist gleich");
3
else
4
  printf("String ist ungleich");
Auch bei der Verkettung von Prozessen in der Konsole mit && arbeiten 
nach dem Prinzip. Wenn die Main-Funktion eines Prozesses !0 zurückgibt 
ist ein Fehler aufgetreten.
Moderator Persönliche Seite #1950452
Lesenswert?

Timmo H. schrieb:
> Es hat sich fast überall so eingebürgert dass wenn eine Funktion "0"
> zurückliefert, sie ohne Fehler durchgelaufen ist.

Dann sollte man aber für den Rückkehrtyp auf keinen Fall "bool"
benutzen, denn dann würde die Funktion "false" zurückgeben, wenn
es in Ordnung war.  Die entsprechende Auswertung (als Boolescher
Wert/Ausdruck benutzt) würde sich völlig widersinnig lesen, und
sowas:
1
if (testfunction_returns_bool() != false) ...

ist kompletter Schwachsinn.  Wenn testfunction_returns_bool() einen
Wert vom Typ "bool" liefert, dann kann man diesen in der if-Anweisung
direkt testen, der zusätzliche Vergleich gegen true oder false bringt
rein gar nichts mehr, denn der Vergleichsoperator liefert per
definitionem auch nur einen Typ "int" mit den möglichen Werten 0 oder
1.
#1950456
Lesenswert?

Jörg Wunsch schrieb:
> Timmo H. schrieb:
>> Es hat sich fast überall so eingebürgert dass wenn eine Funktion "0"
>> zurückliefert, sie ohne Fehler durchgelaufen ist.
>
> Dann sollte man aber für den Rückkehrtyp auf keinen Fall "bool"
> benutzen, denn dann würde die Funktion "false" zurückgeben, wenn
> es in Ordnung war.
Der TO hat auch kein Bool benutzt, das war Jörg

"The C Standard (ISO/IEC 9899:1999 (``ISO C99'')) defines the values 0, 
EXIT_SUCCESS, and EXIT_FAILURE as possible values of status."
Gast #1950472
Lesenswert?

Fehler kann man auch zurückgeben, wenn die Funktion FALSE liefert und 
man dann eine extra Funktion aufruft, z.b. GetLastError(), um den Fehler 
zu ermitteln, wird z.B. in der WINAPI sehr oft gemacht.

Im Prinzip also Geschmackssache, ich sehe das so:

Kann eine Funktion einen Fehlercode zurückgeben, so sollte 0 bedeuten: 
Kein Fehler, z.B. sowas wie
1
Errorcode = OpenDevice();

Kann sie nur mitteilen, ob eine Bedingung erfüllt ist, sollte sie True 
bzw. false zurückliefern, z.B.
1
 if (IsByteReceived()) ....
#1950482
Lesenswert?

Jörg Wunsch schrieb:
> Timmo H. schrieb:
>> Es hat sich fast überall so eingebürgert dass wenn eine Funktion "0"
>> zurückliefert, sie ohne Fehler durchgelaufen ist.
>
> Dann sollte man aber für den Rückkehrtyp auf keinen Fall "bool"
> benutzen, denn dann würde die Funktion "false" zurückgeben, wenn
> es in Ordnung war.

Ich würde in so einem Fall nicht von bool abraten, sondern eher
einen sinnvollen Namen empfehlen.

Bei einem Ausdruck wie:
1
     if( teste_irgendwas() ) ...
ist eine Fehlinterpretation vorprogrammiert, weil "testen"
nichts zum Ergebnis sagt.
"true" und "false" sind ja erstmal neutral; die Zuordnung
zu "gut" oder "schlecht" ist willkürlich.

Schreibt man dagegen in den Namen rein, was das Ergebnis
bedeutet, wird es klar und keiner interpretiert es falsch:
1
     if( irgendwas_in_Ordnung() ) ...
2
     if( irgendwas_geprueft_und_fuer_gut_befunden() ) ...
3
     if( fehler_bei_irgendwas() ) ...
4
     if( irgendwas_gescheitert() ) ...
Moderator Persönliche Seite #1950549
Lesenswert?

Timmo H. schrieb:
> Der TO hat auch kein Bool benutzt, das war Jörg

Ja, aber er hat letztlich nach bool gefragt (klein geschrieben übrigens,
zumindest nach C99).

> "The C Standard (ISO/IEC 9899:1999 (``ISO C99'')) defines the values 0,
> EXIT_SUCCESS, and EXIT_FAILURE as possible values of status."

Das ist aber ausschließlich auf den Rückkehrstatus von main() in
die Umgebung vorgesehen.  Daher beginnen die Namen ja auch mit
EXIT_.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren