schönes c++?



  • nachtrag: warum nicht etwa so?

    void swap (object *a, object *b)
    {
       char *p = (char*)a;
       char *q = (char*)b;
       int s;
       for (s=0; s<izeof(object); s++)
       {
          p[s] = p[s] ^ q[s];
          q[s] = p[s] ^ q[s];
          p[s] = p[s] ^ q[s];
       }
    }
    

    ^^XOR-swap, dürfte keine exception triggern, weil z.b. kein temporärer speicher alloziert werden muss.
    🙂



  • ;fricky schrieb:

    nachtrag: warum nicht etwa so?

    void swap (object *a, object *b)
    {
       char *p = (char*)a;
       char *q = (char*)b;
       int s;
       for (s=0; s<izeof(object); s++)
       {
          p[s] = p[s] ^ q[s];
          q[s] = p[s] ^ q[s];
          p[s] = p[s] ^ q[s];
       }
    }
    

    ^^XOR-swap, dürfte keine exception triggern, weil z.b. kein temporärer speicher alloziert werden muss.
    🙂

    weils langsam ist.



  • Wie kommt man bloß immer auf die Idee, Smart Pointer seien ein GC? 😮

    > und das ist doch die Kompl... äähh Schönheit von c++ das wir uns immer wieder den passenden Pointer aussuchen könnten ...

    Wenn du zu faul bist, kannst du ruhig permanent den shared pointer nehmen. Schaden wird es dir nicht. 🤡

    > Die meisten anderen Sprachen die Exceptions haben, haben auch einen GC und damit muss man schon mal nicht darüber nachdenken, ob man auch bei ner Exception allen Speicher wieder frei gibt.

    Wieso sollte bei einer Exception der ganze Speicher freigegeben werden? Das hat Erläuterungsbedarf. (Oder lieber doch nicht, das bringt nur weiteres Getrolle)
    Es geht bei Exception safety nicht nur um Speicherlecks. z.B. eine fehlerhafte Datenbankänderung oder ein inkonsistenter Zustand, was nicht nur Speicherleichen, zerdonnerte Streams usw. sein müssen, sondern auch logische Inkonsistenz, die es in jeder Sprache gibt. Informiere dich mal - sofern es dich interessiert - über Ausnahmegarantien (Effective C++).

    > dass eine swap-funktion einem die objekte zersemmelt, wenn sie durch eine exception abbricht. klingt für mich nach einem der typischen c++ workarounds, also nichts, was allgemeingültigkeit hat (hätte ja sein können).

    Es geht - wie gesagt - nicht immer nur um zersemmelten Speicher, sondern unerwünschten/unbekannten Zuständen nach einer Exception. Was passiert, wenn das Auswechseln eines Bitmaps scheiterte? Soll das alte angezeigt werden? Soll ein Default angezeigt werden?
    Exceptionsicheres Swap mag C++artig sein. Andere Sprachen haben andere Mittel.

    C#-Exception-safety: http://research.microsoft.com/en-us/projects/specsharp/krml135.pdf



  • ;fricky schrieb:

    wenn ich's richtig verstanden habe, will man mit solchen verrenkungen verhindern, dass eine swap-funktion einem die objekte zersemmelt, wenn sie durch eine exception abbricht.

    mehr. das mußt du eigentlich in einem größeren kontext sehen.
    ums dir einfacher zu machen, schau, wie ein schnelles swap implementiert ist, und tu es so aus geschwindigkeitsgründen.
    warum es sowas in c nicht gibt: weil es da keine templates gibt und keiner eine default-implementierung für swap schreiben könnte, die per dreieckstausch tauscht. da muß man grundsätzlich für jeden neuen typ ein neues swap schreiben. helau. warum es sowas in java nicht gibt: weil es in java nichtmal möglich ist, eine swap-funktion zu bauen.



  • volkard schrieb:

    ;fricky schrieb:

    ^^XOR-swap, dürfte keine exception triggern, weil z.b. kein temporärer speicher alloziert werden muss.

    weils langsam ist.

    relativ langsam, dafür aber ziemlich zuverlässig. man kann manchmal nicht alles haben.

    Ad aCTa schrieb:

    Es geht - wie gesagt - nicht immer nur um zersemmelten Speicher, sondern unerwünschten/unbekannten Zuständen nach einer Exception. Was passiert, wenn das Auswechseln eines Bitmaps scheiterte? Soll das alte angezeigt werden? Soll ein Default angezeigt werden?

    wenn's wirklich wichtig ist, dass sowas nie schiefgeht, dann sollte man bedingungen schaffen, die ein scheitern nahezu unmöglich machen. mit dynamischem speicher haste natürlich immer das risiko des misslingens. deswegen z.b. ein XOR-swap.

    volkard schrieb:

    das mußt du eigentlich in einem größeren kontext sehen.

    ich sehe diesen kontext als unnötig komplexes, eigenwilliges system, von dem man glaubt, sich immer wieder damit arrangieren zu müssen, weils vielleicht in einigen ganz wenigen punkten vorteile hat.

    volkard schrieb:

    ums dir einfacher zu machen, schau, wie ein schnelles swap implementiert ist, und tu es so aus geschwindigkeitsgründen.

    zur laufzeit, würde ich sagen, geht nichts über drei 'memcpys'.

    volkard schrieb:

    warum es sowas in c nicht gibt: weil es da keine templates gibt und keiner eine default-implementierung für swap schreiben könnte, die per dreieckstausch tauscht. da muß man grundsätzlich für jeden neuen typ ein neues swap schreiben. helau.

    in C kann man eine funktion oder ein makro für'n dreieckstausch basteln, der müsste man zwei pointer und die grösse der objekte mitgeben. das sollte eigentlich klappen. oder man swappt einfach zwei pointer, aber das ist ja nicht dasselbe.

    volkard schrieb:

    weil es in java nichtmal möglich ist, eine swap-funktion zu bauen.

    doch klar. natürlich keine, die im speicher zweier Java-objekte rumwurschtelt, aber mit arrays und einfachen typen geht das schon.
    🙂



  • ;fricky schrieb:

    doch klar. natürlich keine, die im speicher zweier Java-objekte rumwurschtelt, aber mit arrays und einfachen typen geht das schon.

    mach mal und zeig mal.



  • Nanyuki schrieb:

    Ja, ich habe mich etwas unglücklich ausgedrückt. Wenn ich mir so meinen Code anschaue, dann wandern viele mit new erzeugte Objekte sofort in einen Container, der sich fortan um die Speicherverwaltung kümmert. [...]

    Ich wuerde dein Design nochmal ueberpruefen. Immer die Regel beachten, wer den Speicher anfordert ist auch fuer ihn zustaendig. Wieso koennen deine Container nicht die Objekte selbst erzeugen?



  • volkard schrieb:

    ;fricky schrieb:

    doch klar. natürlich keine, die im speicher zweier Java-objekte rumwurschtelt, aber mit arrays und einfachen typen geht das schon.

    mach mal und zeig mal.

    mit einfachen typen gehts wie in C, mit arrays geht's z.b. damit: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#arraycopy(java.lang.Object, int, java.lang.Object, int, int)
    🙂



  • ;fricky schrieb:

    volkard schrieb:

    ;fricky schrieb:

    doch klar. natürlich keine, die im speicher zweier Java-objekte rumwurschtelt, aber mit arrays und einfachen typen geht das schon.

    mach mal und zeig mal.

    mit einfachen typen gehts wie in C, mit arrays geht's z.b. damit: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#arraycopy(java.lang.Object, int, java.lang.Object, int, int)
    🙂

    Kannst Du was bauern, das

    int a=4;
    int b=5;
    swap(a,b);
    

    ermöglicht? Ja oder nein? Wenn ja, gib Code an.



  • ;fricky schrieb:

    ^^XOR-swap, dürfte keine exception triggern, weil z.b. kein temporärer speicher alloziert werden muss.

    Exceptionsicheres Swap löst per Definition keine Exceptions aus, weil es sich bei korrekter Implementierung am Ende nur um Dreieckstausch von PODs handelt. Und ein temporär erstelltes POD-Objekt ist nie ein Problem. Hingegen vergisst du, dass bei Nicht-POD-Typen nicht in den Bits herumgefummelt werden darf, ohne undefiniertes Verhalten zu erzeugen. Sowas wie memcpy() oder XOR geht also in den meisten Fällen nicht.

    ;fricky schrieb:

    wenn's wirklich wichtig ist, dass sowas nie schiefgeht, dann sollte man bedingungen schaffen, die ein scheitern nahezu unmöglich machen.

    Klingt sehr einfach. Wie stellst du dir das vor?

    ;fricky schrieb:

    mit einfachen typen gehts wie in C, mit arrays geht's z.b. damit: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/System.html#arraycopy(java.lang.Object, int, java.lang.Object, int, int)

    Naja, aber sowas wie Swapper.swap(a,b) mit Referenztausch ist eben nicht möglich (bzw. nur für ein paar Spezialfälle). Darum gehts doch: In C++ kann man mit swap() schlichtweg alles tauschen.

    DEvent schrieb:

    Ich wuerde dein Design nochmal ueberpruefen. Immer die Regel beachten, wer den Speicher anfordert ist auch fuer ihn zustaendig. Wieso koennen deine Container nicht die Objekte selbst erzeugen?

    Grundsätzlich stimmt die Regel schon. Container werden aber normalerweise dazu verwendet, eine abstrakte Schnittstelle für den Anwender zu haben -- sprich: Dem Container selbst ist es egal, was er für Elemente besitzt. Folglich sollte er auch nicht für die Erzeugung verantwortlich sein, weil das die Generizität und Wiederverwendbarkeit sehr stark einschränkt.

    Der Normalfall ist sowieso, dass man "normale" Objekte und keine besitzenden Zeiger einfügt. Weil man aber ab und zu deren Flexibilität braucht und trotzdem nicht manuell freigeben will, gibts auch dafür spezielle Containertypen, die einem die Arbeit abnehmen.



  • volkard schrieb:

    Kannst Du was bauern, das

    int a=4;
    int b=5;
    swap(a,b);
    

    ermöglicht? Ja oder nein? Wenn ja, gib Code an.

    so etwa in Java:

    int[] a = {4,5};
    swap(a);
    

    Nexus schrieb:

    Und ein temporär erstelltes POD-Objekt ist nie ein Problem.

    du brauchst ja irgenwie speicher dafür und speicheranforderungen können nun mal schief gehen.

    Nexus schrieb:

    Hingegen vergisst du, dass bei Nicht-POD-Typen nicht in den Bits herumgefummelt werden darf, ohne undefiniertes Verhalten zu erzeugen.

    stimmt natürlich, wenn das objekt z.b. pointer auf andere objekte hat und sowas, wäre ein speicher-swap vielleicht nicht das richtige.
    btw, da fällt mir ein: in Java könnte man ein objekt-swap mit 'nem Object/Output/InputStream im speicher machen. das macht nebenbei auch gleich tiefe kopien.

    Nexus schrieb:

    ;fricky schrieb:

    wenn's wirklich wichtig ist, dass sowas nie schiefgeht, dann sollte man bedingungen schaffen, die ein scheitern nahezu unmöglich machen.

    Klingt sehr einfach. Wie stellst du dir das vor?

    hängt von der situation ab. wenn man z.b. auf temporären speicher verzichten kann, macht's die sache sicherlich zuverlässiger.
    🙂



  • ;fricky schrieb:

    volkard schrieb:

    Kannst Du was bauern, das

    int a=4;
    int b=5;
    swap(a,b);
    

    ermöglicht? Ja oder nein? Wenn ja, gib Code an.

    so etwa in Java:

    int[] a = {4,5};
    swap(a);
    

    wie baust du swap?
    und komm mir nicht mit lösungen, die so umständlich zu benutzen sind wie

    int a=4;
    int b=5;
    
    //begin swap
    int[] c = {a,b};
    swap(c);
    a=c[0];
    b=c[1];
    //swapped in only 4 lines of code
    


  • ;fricky schrieb:

    volkard schrieb:

    Kannst Du was bauern, das

    int a=4;
    int b=5;
    swap(a,b);
    

    ermöglicht? Ja oder nein? Wenn ja, gib Code an.

    so etwa in Java:

    int[] a = {4,5};
    swap(a);
    

    *lach* Eine Schnistelle für Swappen von zwei Elementen ist etwas anders als ein für ein Container.
    Außerdem hassu noch einige Problem. Was passiert wenn das Array mehr als 2 Elemente hat. Swaps du nur die zwei ersten Elemente oder den gesamten Container?

    Für die eigentliche Swap-Funktion brauchst du die Referenz von der Referenz und das gibst in Java nicht. Aber in C#:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void swap<T>(ref T a, ref T b)
            {
                var c = a;
                a = b;
                b = c;
            }
    
            static void Main(string[] args)
            {
                int a = 1;
                int b = 2;
    
                swap(ref a, ref b);
            }
        }
    }
    


  • avrül schrieb:

    Die meisten anderen Sprachen die Exceptions haben, haben auch einen GC und damit muss man schon mal nicht darüber nachdenken, ob man auch bei ner Exception allen Speicher wieder frei gibt.

    Und da haben wir das Problem. Speicher ist eine von vielen Ressourcen, die man freigeben muss. Aber das Problem trifft auf andere Ressourcen und Programmabläufe zu. zB Datenbankhandels oder Sockets oder im Programmablauf wird ein wichtiger Schritt übersprungen zB in einem Kommunikationsprotokoll mit anderer Software.

    Exceptions führen eben vorher schwer vorhersehbare Programmpfade ein. Daher muss man sich darüber immer Gedanken machen. Egal ob die Sprache nun einen GC hat oder einen zwingt Exceptions zu fangen.



  • Ad aCTa schrieb:

    Wie kommt man bloß immer auf die Idee, Smart Pointer seien ein GC? 😮

    Schreibt wer?

    > und das ist doch die Kompl... äähh Schönheit von c++ das wir uns immer wieder den passenden Pointer aussuchen könnten ...

    Wenn du zu faul bist, kannst du ruhig permanent den shared pointer nehmen. Schaden wird es dir nicht. 🤡

    Passt schon, wenn man auf Memleaks steht

    > Die meisten anderen Sprachen die Exceptions haben, haben auch einen GC und damit muss man schon mal nicht darüber nachdenken, ob man auch bei ner Exception allen Speicher wieder frei gibt.

    Wieso sollte bei einer Exception der ganze Speicher freigegeben werden?

    Passt schon, wenn man auf Memleaks steht

    Es geht bei Exception safety nicht nur um Speicherlecks. z.B. eine fehlerhafte Datenbankänderung oder ein inkonsistenter Zustand, was nicht nur Speicherleichen, zerdonnerte Streams usw. sein müssen, sondern auch logische Inkonsistenz, die es in jeder Sprache gibt.

    Hab ich behauptet, dass es nur um Speicherlecks geht? Tuts ja nicht mal beim copy assignment op.

    ;fricky schrieb:

    Nexus schrieb:

    Und ein temporär erstelltes POD-Objekt ist nie ein Problem.

    du brauchst ja irgenwie speicher dafür und speicheranforderungen können nun mal schief gehen.

    Die haben sich da mit dem Copy-and-swap schon was kompliziert schönes ausgedacht, damit es keine Exception geben kann, auch wenn es Nexus schlecht erklärt. Beruht übrigens auf C++ Innereien.

    Und zu swap in Java. Wozu auch? In Java kann man keine operatoren überladen, was swap zu einer unwichtigen Funktion macht und nicht wie in C++ zur fast wichtigsten.



  • avrül schrieb:

    Und zu swap in Java. Wozu auch? In Java kann man keine operatoren überladen, was swap zu einer unwichtigen Funktion macht und nicht wie in C++ zur fast wichtigsten.

    *lach* Swap ist einer der wichtigen elementare Operationen in Algorithmen.



  • rüdiger schrieb:

    avrül schrieb:

    Die meisten anderen Sprachen die Exceptions haben, haben auch einen GC und damit muss man schon mal nicht darüber nachdenken, ob man auch bei ner Exception allen Speicher wieder frei gibt.

    Und da haben wir das Problem. Speicher ist eine von vielen Ressourcen, die man freigeben muss. Aber das Problem trifft auf andere Ressourcen und Programmabläufe zu. zB Datenbankhandels oder Sockets oder im Programmablauf wird ein wichtiger Schritt übersprungen zB in einem Kommunikationsprotokoll mit anderer Software.

    Exceptions führen eben vorher schwer vorhersehbare Programmpfade ein. Daher muss man sich darüber immer Gedanken machen. Egal ob die Sprache nun einen GC hat oder einen zwingt Exceptions zu fangen.

    Nochmal: Hab ich behauptet, dass es nur um Speicherlecks geht?

    Versucht doch mal richtig zu lesen. Ein Beispiel für ein Problem, dass hauptsächlich bei C++ auftritt, schließt nicht alles andere aus.

    Zeus schrieb:

    avrül schrieb:

    Und zu swap in Java. Wozu auch? In Java kann man keine operatoren überladen, was swap zu einer unwichtigen Funktion macht und nicht wie in C++ zur fast wichtigsten.

    *lach* Swap ist einer der wichtigen elementare Operationen in Algorithmen.

    Bei welcher Sprache findest du das jetzt witzig?



  • Nexus schrieb:

    Ach ja, es wird hier im Thread wahrscheinlich Leute geben, die versuchen, C++ als hässliche, unsichere, mühsame und komplizierte Sprache darzustellen. Du wirst relativ schnell merken, dass sie eine fundamentale Abneigung besitzen und es ihnen nur ums Flamen geht. Schenke ihnen nicht unnötige Beachtung.

    Schenke niemandem unnötige Beachtung. Am besten: tu überhaupt nichts unnötiges. Ich stelle mich der Wahl zum neuen Chef-Esoteriker.
    🙂



  • avrül schrieb:

    Bei welcher Sprache findest du das jetzt witzig?

    Deine Aussage!



  • Zeus schrieb:

    avrül schrieb:

    Bei welcher Sprache findest du das jetzt witzig?

    Deine Aussage!

    Beantwortet jetzt nicht meine Frage. Was findest du witzig?
    1. swap ist in Java eine unwichtige Funktion
    2. swap ist in C++ eine der wichtigsten Funktionen


Anmelden zum Antworten