Einen String an eine Funktion übergeben



  • Hallo liebe C++ Profis,

    ich habe gerade vier Regeln gelesen wie man einen String an eine Funktion übergeben kann. Ich habe mich für die Move Semantik entschieden, da ich den String nach dem Funktionsaufruf nicht mehr brauche. Sind die Regeln korrekt und habe ich das richtig gemacht im Sinne von Performance und Ressourcenverbrauch?

    1. Using the string as an id (will not be modified). Passing it in by const reference is probably the best idea here: (std::string const&)

    2. Modifying the string but not wanting the caller to see that change. Passing it in by value is preferable: (std::string)

    3. Modifying the string but wanting the caller to see that change. Passing it in by reference is preferable: (std::string &)

    4. Sending the string into the function and the caller of the function will never use the string again. Using move semantics might be an option (std::string &&)


  • Mod

    Das ist ein sehr brauchbarer Regelsatz, den du da hast.



  • Danke, dann kommt das in meine C++ Notizen.



  • Vielleicht auch noch:

    Will man eine Kopie des Strings speichern (z.B. in einer Member-Variablen), empfiehlt sich ebenfalls den String by-value
    entgegenzunehmen und diesen dann in das Ziel zu moven. Eine const& hätte hier nämlich den Nachteil, dass wenn
    die Funktion zum Beispiel mit einem C-String-Literal f("abc") aufgerufen wird, zunächst der String als temporäres Objekt
    konstruiert, und dann als const& an die Funktion weitergegeben wird. Von dieser kann man aber nicht moven, daher
    muss der String nochmal kopiert werden.

    Auch wenn der Funktion ein string&& übergeben wird (z.B. mit f(g()) , wobei g einen String by-value zurückgibt) castet
    man sich mit einem const& -Parameter die rvalue-Referenz unnötigerweise einfach weg, ohne davon profitiert zu haben -
    die String-Konstruktoren eines by-value entgegengenommenen Strings nutzen die Tatsache, dass es eine rvalue-Referenz
    ist, jedoch automatisch. Und falls es keine rvalue-Referenz ist: Kopiert werden muss der String sowieso, das kann dann
    auch im Konstruktor des Parameters passieren anstatt in dem des Ziels (z.B. der Member-Variablen).



  • Danke auch an dich für die Erläuterung. Ich übergebe den Text mit einem std::string Literal ""s und speichern ihn auch nicht mehr, der kann einfach wirklich weg nach der Bearbeitung.



  • Das ist zwar wieder ein anderes Thema, aber kann ich irgendwo selbst mit Visual Studio 2017 Community Edition raus finden was mit einem Objekt bei der Übergabe an eine Funktion/Methode passiert? Also ob noch temporäre Kopien gemacht werden und so weiter?


  • Mod

    Es ist möglich, sich den erzeugten Maschinencode anzusehen. Was natürlich voraussetzt, dass du wenigstens halbwegs in der Lage bist, Assembler zu lesen. Hochoptimierter Maschinencode (und nur optimierter Code ist interessant für diese Fragestellung) ist jedoch recht schwer zu lesen, denn da bleibt von high-level Konzepten wie Variablen nicht mehr unbedingt viel übrig. Erschwerend kommt hinzu, dass du von einfachen Testfällen nicht unbedingt auf echte Anwendungen schließen kannst, denn Kontext ist bei Optimierungen wichtig.

    Tendenziell sind die Regeln, die du genannt hast, so formuliert, dass sie es dem optimierenden Compiler besonders einfach machen. Ein halbwegs guter Compiler (VC++ ist halbwegs gut) kann oft aber noch viel mehr optimieren, selbst wenn obige Regeln es unter strenger Auslegung eigentlich nicht erlauben, weil er den Kontext ansehen kann (siehe Bemerkung über Kontext) und dann erkennen kann, dass da vielleicht doch etwas geht. Beispielsweise konnten Compiler schon lange move-Übergaben erzeugen, bevor diese mit dem Sprachstandard C++11 formalisiert wurden. Der Compiler kann schließlich sehen, ob eine Variable nach einer Übergabe nicht mehr benutzt wird.



  • Besten Dank für den Einblick. Assembler kennen ich nur noch vom 64er, Amiga und ganz ganz wenig x86. So tief wollte ich jetzt nicht gehen, aber interessant ist es dennoch. In der erste Linie will ich den Grundstock von modernem C++ mir erarbeiten, in dem ich mir selbst kleine Projekte schreibe und dann von den vielen Fehlern, die ich dabei mache, lerne.

    Als Lektüre habe ich mir "Der C++ Programmierer" bestellt. Die Ausgabe die auch schon C++17 mit an Bord hat. Mal schauen, ob ich als alter Hase das noch auf die Reihe bekomme mit dem C++ lernen.

    Danke euch für die großartige Hilfsbereitschaft hier.


Anmelden zum Antworten