Return in Schleife

Gast
kurz noch ein guter Rat.

return immer nur am Ende einer C-funktion. Natürlich kann es überall 
stehen, aber wenn es mal zum Fehlersuchen oder Laufzeitmessen kommt sind 
die ersten Probleme vorprogrammiert. Dieses versteckte return wird dann 
einfach übersehen.

Ein guter Programierstil hat immer nur 1 return und das am Ende.


JL
jl wrote:

> Ein guter Programierstil hat immer nur 1 return und das am Ende.

Wie würdest du folgendes realisieren:
Laderoutine für irgendeine Datei. fopen liefert NULL, also wird direkt 
ein Fehler zurückgegeben. Meist sieht das dann so aus:
if (fp==NULL)
 return -1;

Dann die eigentliche Laderoutine mit weiteren Fehlerabfragen und return 
-2, -3 usw. und ganz am Ende:

return 0;
Gast
Das "return nur am Ende der Funktion" Dogma muss man sich gut überlegen. 
Da gibt es dann Experten, die verkomplizieren den Code durch eigentlich 
überflüssige Hilfsvariablen, weil sie unbedingt nur ein return am Ende 
der Funktion haben wollen. Das ist natürlich bullshit.
Gast
Returns vor dem Funktionsende sind (ähnlich wie Breaks und Continues)
getarnte und und in ihren Möglichkeiten eingeschränkte Verianten des
Gotos. Alle diese Anweisungen haben aber auch ihren Sinn, zumindest
aus Sicht der Entwickler der Sprache C, sonst gäbe es sie nicht. Ob
die Verwendung einer dieser Anweisungen guter oder schlechter Stil
ist, hängt davon ab, welche Effizienz- oder Lesbarkeitseinbußen die
Umgehung dieser Anweisungen nach sich ziehen würde, und wie Effizienz
und Lesbarkeit im konkreten Programmteil gewichtet sind.
>Oder kurz ausgedrückt: Es ist Geschmackssache, wie so vieles!

So ist es... in Zeiten der objektorientierten Programmierung ist der 
Ausstieg z.B. über Exceptions sogar durchaus üblich.

Ich versuche immer so schnell wie möglich aus der Funktion/Schleife 
rauszukommen und vermeide damit unnötig tiefe Schachtelungen und zig. 
Flags.

Muss natürlich entsprechend kommentiert werden, damit es lesbar bleibt.

Wird es doch zu unübersichtlich ist das eher ein Zeichen dafür, dass der 
Code weiter zerlegt werden sollte.

Muss natürlich je nach Einzelfall entschieden werden.

Gibt ja auch Leute, die versuchen fußgesteuerte Schleifen, den ternären 
Operator und +=, ^=, <<=, etc zu vermeiden/verbieten... man kann es sich 
auch schwer machen.
Kai Giebeler wrote:
>>Oder kurz ausgedrückt: Es ist Geschmackssache, wie so vieles!
>
> So ist es... in Zeiten der objektorientierten Programmierung ist der
> Ausstieg z.B. über Exceptions sogar durchaus üblich.
>
und da kommt es wieder auf die Sprache an.
In C++ sollte man es tunlichst vermeiden, reguläre Ausstiege mit 
exceptions zu machen, exceptions sollten da nur für Fehlerbehandlung 
verwendet werden....
Gast
> return immer nur am Ende einer C-funktion.

Macht oft den Code unnötig kompliziert. Ich prüfe oft am Anfang einer 
Funktion die Vorbedingungen ab und kehre dann ggf. direkt mit einem 
return zurück. Warum soll ich da den gesamten Funktionsinhalt in eine 
Verschachtelung aus mehreren ifs stecken?

Was sieht einfacher übersichtlicher aus:

[C
file_id file_create(const char* name)
{
    file_id ret;
    if (name != NULL)
    {
        if (!file_id_pool_full())
        {
            if (!file_exists(name))
            {
                if (can_create(name))
                {
                    // ok, create the file
                    ret = ...
                }
                else
                {
                    ret = -1;
                }
            }
            else
            {
                ret = -2;
            }
        }
        else
        {
            ret = -3;
        }
    }
    else
    {
        ret = -4;
    }

    return ret;
}
[/C]

oder
1
file_id file_create(const char* name)
2
{
3
   // check all the preconditions
4

5
   if (name == NULL)
6
       return -4;
7

8
    if (file_id_pool_full())
9
       return -3;
10

11
    if (file_exists(name))
12
       return -2;
13

14
    if (!can_create(name))
15
       return -1;
16

17
    // ok, create the file
18
    return ...
19
}

> Dieses versteckte return wird dann einfach übersehen.

Man könnte auch argumentieren, daß die Funktion zu lang bzw. zu komplex 
ist, wenn die returns dadurch so versteckt werden, daß man sie übersehen 
kann.

> Returns vor dem Funktionsende sind (ähnlich wie Breaks und Continues)
> getarnte und und in ihren Möglichkeiten eingeschränkte Verianten des
> Gotos.

> in Zeiten der objektorientierten Programmierung ist der Ausstieg z.B.
> über Exceptions sogar durchaus üblich.

Die sind in der Hinsicht eigentlich schlimmer als goto, da sie nicht nur 
direkt in der aktuellen Funktion selbst, sondern auch irgendwo anders in 
einer aufgerufenen Funktion geworfen werden können und entsprechend auch 
in irgendeinem Aufrufer gefangen werden können. Beim goto stehen Start 
und Ziel des Sprungs wenigstens in der selben Funktion, und sie sind zur 
Compilezeit festgelegt.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 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.