C++ Standardisierung: Ein erster Blick auf die Papers & C++14



  • Letztendlich sind das doch alles unwichtige Kleinigkeiten

    👍
    Aber einige davon sind schon doch witzig. Das mit den Literalen bspw. 😃



  • Gerade Allokatoren sind etwas, wo ich den Template-Ansatz einfach falsch finde. Allokatoren haben ein klares Interface, das nicht zum Typen gehoeren sollte.

    Ich schlage mal folgendes vor:

    struct memory_allocator
    {
        virtual void* allocate(std::size_t size) = 0;
        virtual bool reallocate(void* ptr, std::size_t new_size) = 0;
        virtual void free(void* ptr) = 0;
    
        virtual ~memory_allocator() {}
    
        // new, delete
        static memory_allocator& get_default();
        static void set_default(memory_allocator& alloc);
    };
    

    Einwaende?



  • Kellerautomat schrieb:

    Gerade Allokatoren sind etwas, wo ich den Template-Ansatz einfach falsch finde. Allokatoren haben ein klares Interface, das nicht zum Typen gehoeren sollte.

    Das sehe ich anders. Ein Container ist dafür zuständig, Elemente für den Anwendungszweck angepasst zu speichern und das hängt durchaus stark mit Allokatoren zusammen.

    Davon abgesehen entsteht dadurch ein gewisser Overhead, nämlich zusätzlicher Speicherverbrauch (mind. 1 Pointer pro Container) und zusätzliche Indirektionen.

    Das wirkliche Problem ist, den Inhalt zu abstrahieren, dafür sind (möglicherweise type-erased) Ranges da. Oder man leitet vector<int> von random_acces_range<int> ab. Aber nicht in dem man den Allokator erased.

    Abgesehen davon:

    virtual void* allocate(std::size_t size) = 0;
    

    Sollte mMn char* zurückgeben, aber das ist erstmal irrelevant.

    virtual bool reallocate(void* ptr, std::size_t new_size) = 0;
    

    Wie benutzt man das? Meintest du char*& ptr ?

    virtual void free(void* ptr) = 0;
    

    noexcept ...

    // new, delete
    static memory_allocator get_default();
    static void set_default(memory_allocator& alloc);
    

    Das sollte eher memory_allocator& get_default() mit [s|g]et_default_memory_factory() sein um Allokatoren mit Zuständen zu erlauben.

    Eine Überlegung wert wäre noch das Alignment mit einzubeziehen, weil das für small object allocators ganz nützlich sein könnte, also

    virtual char* allocate(std::size_t size, std::size_t alignment = /* default alignment */) = 0;
    virtual bool reallocate(char*& ptr, std::size_t new_size, std::size_t alignment = /* previously used alignment */) = 0;
    


  • Kellerautomat schrieb:

    realloc done right

    Hier muss man aufpassen, weil realloc in C++ nur Speicherblöcke vergrössert oder neue alloziert, und dabei weder Inhalte kopiert noch alte freigibt.



  • polynom schrieb:

    Eine Überlegung wert wäre noch das Alignment mit einzubeziehen, weil das für small object allocators ganz nützlich sein könnte

    Ausserdem ist es für SIMD notwendig.

    Deshalb sollte std::aligned_storage für *alle* Zweierpotenz-Alignments definiert sein und nicht nur für eine unbestimmte Anzahl.



  • polynom schrieb:

    Das sehe ich anders. Ein Container ist dafür zuständig, Elemente für den Anwendungszweck angepasst zu speichern und das hängt durchaus stark mit Allokatoren zusammen.

    Der Allokator ist lediglich dafuer verantwortlich, wo der speicher herkommt, das ist doch keine Eigenschaft des Containers. Warum sollte ein Container ueberhaupt einen Allokator besitzen (= als Member haben)? Das ergibt im momentanen Standard alles keinen Sinn.

    polynom schrieb:

    Davon abgesehen entsteht dadurch ein gewisser Overhead, nämlich zusätzlicher Speicherverbrauch (mind. 1 Pointer pro Container) und zusätzliche Indirektionen.

    Verstehe ich gerade nicht.

    polynom schrieb:

    Das wirkliche Problem ist, den Inhalt zu abstrahieren, dafür sind (möglicherweise type-erased) Ranges da. Oder man leitet vector<int> von random_acces_range<int> ab. Aber nicht in dem man den Allokator erased.

    Concepts, die wir hoffentlich in C++14 zumindest in einer Lite-Version auch noch bekommen.

    polynom schrieb:

    Abgesehen davon:

    virtual void* allocate(std::size_t size) = 0;
    

    Sollte mMn char* zurückgeben, aber das ist erstmal irrelevant.

    Sehe ich anders. void* heisst fuer mich einfach Zeiger auf "nichts bestimmtes" oder "irgendwas". Also roher Speicher.

    polynom schrieb:

    virtual bool reallocate(void* ptr, std::size_t new_size) = 0;
    

    Wie benutzt man das? Meintest du char*& ptr ?

    Nein. reallocate() versucht inplace zu reallozieren und gibt zurueck, ob das gelingt. Wenn nicht, muss der Benutzer selbst mit allocate() einen neuen Bereich allozieren. Dafuer kann er aber auch copy/move Ctoren aufrufen.

    polynom schrieb:

    virtual void free(void* ptr) = 0;
    

    noexcept ...

    Die Funktionen sind alle noexcept, hab daran gar nicht gedacht auf die Schnelle.

    polynom schrieb:

    // new, delete
    static memory_allocator get_default();
    static void set_default(memory_allocator& alloc);
    

    Das sollte eher memory_allocator& get_default() mit [s|g]et_default_memory_factory() sein um Allokatoren mit Zuständen zu erlauben.

    Niemand besitzt einen Allokator. Die werden per Referenz herumgereicht. Daher ist es auch egal, ob der Zustand hat, oder nicht.

    Edit: Achso, ja. Ich habe die Referenz hier vergessen.

    polynom schrieb:

    Eine Überlegung wert wäre noch das Alignment mit einzubeziehen, weil das für small object allocators ganz nützlich sein könnte, also

    virtual char* allocate(std::size_t size, std::size_t alignment = /* default alignment */) = 0;
    virtual bool reallocate(char*& ptr, std::size_t new_size, std::size_t alignment = /* previously used alignment */) = 0;
    

    Bei alignment bin ich mir unsicher. Waere aber wohl eine Ueberlegung wert. reallocate braeuchte aufgrund meiner obigen Definition allerdings keinen alignment-Parameter. Du dachtest hier bestimmt an ein C-realloc, das aber eben fuer C++ unbrauchbar ist.



  • Och, es gibt schon einige recht interessante Proposals: Polymorphic Lambdas, Resumable Functions, SIMD, Unicode, 🙂



  • Sone schrieb:

    Aber du weißt schon, dass meine Begeisterung hauptsächlich daher kommt, da ich mich selbst daran versucht hab? Such mal "Dynarray Implementation"

    Ich weiß, dass du das versucht hast.
    Zu dem Zeitpunkt habe ich mitgelesen und ab und zu nicht angemeldet geschrieben.
    Trotzdem habe ich einige Situationen, bei der ein vector zu viel ist.



  • Der einzige Zweck von dynarray ist dass es zb über alloca implementiert werden könnte. Ein vector für Arme ist wohl kaum eine sinnvolle Neuerung. 😉



  • Ethon schrieb:

    Der einzige Zweck von dynarray ist dass es zb über alloca implementiert werden könnte. Ein vector für Arme ist wohl kaum eine sinnvolle Neuerung. 😉

    Nö, ich finde nach wie vor, dass dynarray meinen Bedürfnissen entspricht. Manchmal brauche ich ein Array, das eben eine zur Laufzeit bekannte Größe hat, aber diese nicht verändern kann. Ich verstehe nicht, wieso ich da in vector einen Kompromiss sehen muss. Das ist kein Overbloat.



  • Naja, mich haut von den proposals jetzt nichts wirklich vom Hocker.

    //edit hätte ich mehr zeit, würde ich ja meine "structural constness" ins Rennen werfen, aber momentan kann ich nicht die notwendige Zeit investieren, ein gutes proposal paper zu schreiben...



  • Sone schrieb:

    Manchmal brauche ich ein Array, das eben eine zur Laufzeit bekannte Größe hat, aber diese nicht verändern kann. Ich verstehe nicht, wieso ich da in vector einen Kompromiss sehen muss. Das ist kein Overbloat.

    Ob es nützlich ist, ist eine Sache. Ob es in die Standardbibliothek muss, eine andere. Meiner Meinung nach gibt es viel wichtigere Dinge als so ein Spezialfall von Container, der so gut wie keine Vorteile gegenüber std::vector bringt. Da wären einige Klassentemplates aus Boost.Container (z.B. stable_vector oder flat_map ) massiv bessere Kandidaten.

    otze schrieb:

    Naja, mich haut von den proposals jetzt nichts wirklich vom Hocker.

    Ja, bisher gibts keine Killerfeatures. std::optional scheint mir am nützlichsten zu sein.

    Bei gewissen Features wie dem const type| -Qualifizierer frage ich mich, wieso es dauernd Leute gibt, die für nahezu-nutzlose Features bereit sind, die Komplexität des Typsystems weiter zu erhöhen 🙄



  • otze schrieb:

    Naja, mich haut von den proposals jetzt nichts wirklich vom Hocker.

    C++14 wird ja eigentlich auch nur dazu da sein, C++11 zu verbessern.
    Z.b. Polymorphic Lambdas oder then() für std::future/std::shared_future.
    Hab mich gestern durch weitere 9 Papers gelesen, da sind schon interessante Sachen dabei,
    aber auch die Frage, was letzten endes dann wirklich wie durchs Committee kommt.

    Im Bereich Parallelism sind viele interessante Proposals, aber wie man die wieder sinnvoll unter einen Hut bekommt ist wohl die Preisfrage.

    Wer von euch nutzt eigentlich schon C++11 aktiv?



  • Ich glaube fast alle.



  • otze schrieb:

    //edit hätte ich mehr zeit, würde ich ja meine "structural constness" ins Rennen werfen, aber momentan kann ich nicht die notwendige Zeit investieren, ein gutes proposal paper zu schreiben...

    Das ist auch sowas. Statt die richtigen Probleme anzugehen (Modulsystem, Concepts), werden tausend kleine Änderungen vorgeschlagen, die in einzelnen Spezialfällen minimale Vorteile bringen. Im Grossen betrachtet führen sie aber zu vielen Nachteilen, weil die Sprachintegration sich als schwierig erweist und viele Probleme mit sich bringt, die anfänglich nicht sichtbar sind. Für so eine grundlegende Änderung wie const muss meiner Meinung nach eine extrem gute Rechtfertigung vorhanden sein. Warum das bei struct const nicht der Fall ist, habe ich hier erklärt.

    Mit jedem neuen Sprachmittel wird C++ noch einmal komplexer, Leute brauchen noch einmal länger, um die Sprache zu lernen, und es bilden sich noch mehr inkompatible Codestile. Würde mich nicht wundern, wenn die massive Häufung solcher "Features" letzen Endes das Todesurteil von C++ bedeutete. Mittelfristig wird sie mindestens zu einer Spaltung in der Community führen (wenn das mit C++11 nicht schon längst passiert ist). Ich finde, man sollte versuchen dem entgegen zu wirken, und langfristig auch über abwärts-inkompatible Änderungen nachdenken. Natürlich ist das leichter gesagt als getan, aber ich hoffe zumindest, dass das Kommitee sehr restriktiv im Bezug auf solche Proposals ist...

    phlox81 schrieb:

    Wer von euch nutzt eigentlich schon C++11 aktiv?

    Dauernd, zumindest die portabel einsetzbaren Features: RValue-Referenzen, nullptr , Lambda-Expressions, Smart Pointers, ...

    std::make_unique() muss unbedingt mit C++14 kommen.



  • Nathan schrieb:

    Ich glaube fast alle.

    Das glaube ich nicht.
    Viele Compiler unterstützen es gerade erst, und in vielen Projekten wird noch sehr lange der ältere Standard verwendet werden.
    Für eigenen Code gilt das natürlich häufig nicht.



  • Nexus schrieb:

    otze schrieb:

    Naja, mich haut von den proposals jetzt nichts wirklich vom Hocker.

    Ja, bisher gibts keine Killerfeatures. std::optional scheint mir am nützlichsten zu sein.

    wtf? Was wäre an SIMD und ernsthafter Unicode Unterstützung bitte kein "Killerfeature"? Beides ist sicherlich hilfreicher als optional.

    Nexus schrieb:

    Das ist auch sowas. Statt die richtigen Probleme anzugehen (Modulsystem, Concepts), werden tausend kleine Änderungen vorgeschlagen, die in einzelnen Spezialfällen minimale Vorteile bringen.

    1. Wurde doch schon 2011 gesagt dass C++14 primär eine Library Erweiterung wird und Dinge wie Concepts und Modules erst 2017 kommen.
    2. Würde ich filesystem, network SIMD und Unicode nicht als "kleine Änderungen, die in einzelnen Spezialfällen minimale Vorteile bringen" bezeichnen.



  • Ich bezog mich auf die Proposals auf phlox81s Seite. Deshalb "bisher"

    "Kleine Änderungen, die in einzelnen Spezialfällen minimale Vorteile bringen" war eine Reaktion auf Vorschläge wie struct const oder const| .



  • Nexus schrieb:

    Ich bezog mich auf die Proposals auf phlox81s Seite. Deshalb "bisher"

    "Kleine Änderungen, die in einzelnen Spezialfällen minimale Vorteile bringen" war eine Reaktion auf Vorschläge wie struct const oder const| .

    Alle Proposals findest du hier: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/#mailing2013-03

    Ja, von type| bin ich auch nicht sehr begeistert, man muss aber immer sehen, dass das ja nur Vorschläge sind.
    Denke dass sowas nicht durch Committee kommt. Generell wird es alles schwer haben, was veränderungen an der Sprache vornehmen will.
    Mit Ausnahmen der Proposals welche sich auf C++11 features beziehen, und diese verbessern oder erweitern.



  • Oh, okay. Sorry Nexus.


Anmelden zum Antworten