Was gibt die Funktion zurück?



  • Ich habe eine Funktion, die folgendermaßen aufgerufen wird:

    World.getPlayer(1)->Start();
    
    vector<Player> v_player;
    
    Player &getPlayer(int index)
    {
       if (v_player[index].getName() == "Peter")
         return &v_player[index]
    
       //return NULL;
    }
    

    Es wird bei Aufruf überprüft, ob der Spieler mit angegebenem Index "Peter" heißt. Wenn ja, wird eine Referenz auf den Spieler zurückgegeben und daraufhin Start() ausgeführt.

    Nun soll, wenn die Bedingung false ist, dass eben nichts passiert.
    Wenn ich den Kommentar auskommentiere (und es keinen "Peter" gibt), bekomme ich einen Runtime-Fehler.
    Lasse ich es so, passiert nichts.

    Ich möchte einfach nur die Warnung "Nicht alle Steuerelementpfade geben einen Wert zurück." beseitigen.
    Was genau wird zurückgegeben, wenn ich selbst kein return angebe?

    Danke im Voraus!



  • So wie es aussieht, willst du doch einen Zeiger zurück gekommen, oder?
    Dann ändere den Rückgabewert entsprechend:

    Player* getPlayer(int index)
    {
       if (v_player[index].getName() == "Peter")
         return &v_player[index]
    
       return NULL;
    }
    


  • Referenzen können nicht NULL sein. Benutze entweder wie gezeigt Zeiger oder wirf im Fehlerfall eine Exception. Eine dritte Möglichkeit wäre eine Funktion mit Output-Parameter, der nur im Erfolgsfall benutzt wird:

    bool getPlayer(int index, Player& out);
    

    Übrigens: Für eine Get-Funktion sollte getPlayer() konstant sein. Dann findest du vielleicht heraus, dass der std::map::operator[] nicht mehr anwendbar ist, weil er manchmal Objekte einfügt. Die Alternative wäre std::map::find() .



  • Jockelx schrieb:

    So wie es aussieht, willst du doch einen Zeiger zurück gekommen, oder?
    Dann ändere den Rückgabewert entsprechend:

    Das war ein Tippfehler von mir 🙄 Ich gebe ja schließlich einen Zeiger auf das Element zurück.

    Das Problem ist ja, dass wenn in der Funktion kein return ausgeführt wird, dass auch kein Laufzeitfehler kommt. Demnach passiert einfach nichts.
    Wird hingegen etwas zurückgegeben, bekomme ich Fehler. Die Hauptfrage war, was von der Funktion im Endeffekt zurückgegeben wird, wenn kein return ausgeführt wird?

    Nexus schrieb:

    Referenzen können nicht NULL sein. Benutze entweder wie gezeigt Zeiger oder wirf im Fehlerfall eine Exception. Eine dritte Möglichkeit wäre eine Funktion mit Output-Parameter, der nur im Erfolgsfall benutzt wird:

    bool getPlayer(int index, Player& out);
    

    Das Problem hierbei ist, dass die Funktion als Methode aufgerufen wird, und vom Rückgabewert eine andere Methode ausführt:

    World.getPlayer(1)->Start();
    

    Hierbei möchte ich einfach, dass wenn die Funktion einen Fehler hervorruft, dass dann oberer Code nicht ausgeführt wird. Genau so passiert es im Moment, weil ich keinen Rückgabewert angebe. Hier ein mögliches Beispiel:

    //Bei "return NULL;"
    World.NULL->Start(); //Gibt natürlich einen Fehler

    //Bei keinem return
    World.😕->Start(); //Gibt keinen Fehler, nichts passiert

    btw..
    AFAIK können Referenzen außerdem NULL sein (NULL-Zeiger), sie können nur nicht weiterverwendet werden.



  • I : einen dummy-Player erstellen, der beim Aufruf von Start nichts macht.

    return &player::dummy; // player::dummy.start() macht nichts
    

    II : ein Funktionsobjekt übergeben, die für dich etwas aufruft, wenn Erfolg

    template <class UnaryOperator>
    bool doPlayer(int index, UnaryOperator fnc)
    {
       if (v_player[index].getName() == "Peter") {
          fnc(v_player[index]);
          return true;
       }
       return false;
    }
    
    World.doPlayer(1, std::mem_fun(&player::start));
    

    III : Ganz normal, wie man es in C machen würde:

    player *p;
    if ((p = world.get_player(1))) p->start()
    

    IV : Ganz normal, wie man es in C++ machen würde:

    world::player_iterator it = world.find_player(1);
    if (it != world::player_npos) p->start()
    


  • Dbof schrieb:

    btw..
    AFAIK können Referenzen außerdem NULL sein (NULL-Zeiger), sie können nur nicht weiterverwendet werden.

    Zeiger != Referenzen.
    Referenzen können nicht ungültig sein. Zumindest nicht direkt, man kann es natürlich erzwingen, aber das benötigt ungeschicktes Verhalten.

    int* n = new int(2);
    int& rn = *n;
    delete n;
    std::cout << rn; // autsch
    

    0 kann aber eine Referenz nicht sein.



  • C++-Standard schrieb:

    Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the "object" obtained by dereferencing a null pointer, which causes undefined behavior.



  • Mal eine Frage an die Experten:

    Dbof schrieb:

    //Bei "return NULL;"
    World.NULL->Start(); //Gibt natürlich einen Fehler

    //Bei keinem return
    World.😕->Start(); //Gibt keinen Fehler, nichts passiert

    Wieso gibt der untere Aufruf keinen Fehler? Was wird in dem Fall zurückgegeben?



  • Dbof schrieb:

    Das Problem ist ja, dass wenn in der Funktion kein return ausgeführt wird, dass auch kein Laufzeitfehler kommt.

    Dann schalte doch mal die Compiler-Warnungen auf eine höhere Stufe. Bei einer Funktion wie dieser hier:

    int silly(int a) 
    {
      if (a==3) return 42;
    }
    

    ruft ein Aufruf wie silly(5) undefiniertes Verhalten hervor. Wenn ich mich richtig erinnere sieht der Standardtext sinngemäß so aus: "Flowing off the end of a function with a non-void return type without a return statement invokes undefined behaviour". Bin grad zu Faul, Kapitel und Vers rauszusuchen. Das heißt, dass es Für Deine Frage keine Antwort gibt. Es kann alles mögliche passieren. Das Verhalten ist eben nicht definiert. Du solltest es deswegen vermeiden.

    So etwas ist nur bei der main-Funktion erlaubt. Der Effekt ist dann äquivalent zu einem return EXIT_SUCCESS;

    kk


  • Administrator

    1. Buch Mose, Kapitel 6.6.3, Vers 2 schrieb:

    Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.

    🤡

    Grüssli


Anmelden zum Antworten