Verhindere Copy bei Return im Debug-Modus



  • Hallo,

    ich spiele aktuell etwas mit Selene rum und bin auf ein kleines Problem gestoßen. Zuerst mal schnell mein kurzer Code zur verdeutlichung:
    Lua:

    function ltest()
        print("Hello World");
    end
    

    C++:

    int main(){
    	sel::State state{ true };
    	state.Load("player.lua");
    
    	auto ltest = state["ltest"];
    	ltest();
    
    	system("pause");
    }
    

    Das Problem nun: Wenn ich das ganze als "Debug" Kompiliere und teste, bekomme ich "Hello World" zwei mal ausgegeben, im Releasemodus nicht. Ich denke, das liegt an der "named return value optimisation", kurzer Code aus dem Operator():

    template <typename... Args>
        const Selector operator()(Args... args) const {
            auto tuple_args = std::make_tuple(std::forward<Args>(args)...);
            constexpr int num_args = sizeof...(Args);
            Selector copy{*this};
            copy._functor = [this, tuple_args, num_args](int num_ret) {
                detail::_push(_state, tuple_args);
                lua_call(_state, num_args, num_ret);
            };
    	return copy;  
        }
    

    Die eigentliche lua-funktion (_functor) wird dann im Destruktor aufgerufen. Ich denke, im Debug-Modus wird das ganze doppelt aufgerufen, da 'copy' aus der Funktion rauskopiert wird, im releasemodus aber eben named return value optimization einspringt, sodass das ganze schon am richtigen ort erstellt wird und garnicht mehr kopiert werden muss. Jetzt habe ich versucht, das ganze so zu lösen:

    #ifdef _DEBUG
    			return std::move(copy);
    	#else
    			return copy;
    	#endif
    

    Was aber garnichts bewirkt, es wird immernoch aus irgendeinem grund am ende vom operator() eine kopie von 'copy' erstellt und ich erhalte somit doppelt das "Hello World".

    Hat jemand eine Idee was ich versuchen könnte und kann mir auch jemand erklären, warum das std::move nicht geht und falls es eine dumme Idee war, warum?



  • Hab den Fehler schon gefunden 😕
    Ohne NRVO im Debug-Modus versucht der Compiler das ganze schon selbst zu moven, d.h. das std::move war unnötig (Das ist RVO wenn ich mich nicht irre?!), das Problem war aber, dass ich garkein Move-Konstruktor hatte...

    Das größte Problem was ich an C++ aktuell noch habe ist, dass ich bei jedem Zeichen das ich tippe angst habe, dass ich irgendwas ausversehn kopiere und dann eben genau solche Fehler entstehen. Gibts da irgendwelche Tipps zu, wie man da eben besser reinkommt zu verstehen, wann kopiert wird und wann nicht?


Anmelden zum Antworten