Dynarray Implementation



  • Und noch eine Frage:
    soll ich
    allocator_type::propagate_on_container_copy_assignment , `

    allocator_type::propagate_on_container_move_assignment und

    allocator_type::propagate_on_container_swap

    `
    Mit einbeziehen?



  • Sone schrieb:

    Her mit der Kritik :xmas1:

    Danke im Voraus,
    MfG :xmas2:

    Edit: Erneuere jetzt den Code immer hier.

    Interessante Sache, aber mach das bitte auf Github oder so. Das Forum ist nicht die beste Versionsverwaltung.

    Sone schrieb:

    camper schrieb:

    9. noexcept für Destruktor, move-Konstruktor/Zuweisung etc.

    Schwierige Sache, da schon im Dtor das deallokieren vom Allokator nicht zwangsläufig nothrow sein muss.
    (Oder das zerstören der Feldelemente)

    Wenn ein Destruktor wirft, wird das Programm ohnehin terminiert (oder schlimmeres). Deswegen muss man diesen Fall nicht behandeln.



  • Müsste _deallocateAll nicht in einer Endlosschleife enden? Schließlich ruft es sich selber ohne eine Bedingung auf. Oder was ist der Sinn dahinter?



  • Hmmmmmm schrieb:

    Müsste _deallocateAll nicht in einer Endlosschleife enden? Schließlich ruft es sich selber ohne eine Bedingung auf. Oder was ist der Sinn dahinter?

    Hahahahaha 😃
    Das war ein kleines Malheur mit der Replace-Funktion meiner IDE 😃 😃 😃 👍 👍

    Korrigiert 😃



  • TyRoXx schrieb:

    Sone schrieb:

    camper schrieb:

    9. noexcept für Destruktor, move-Konstruktor/Zuweisung etc.

    Schwierige Sache, da schon im Dtor das deallokieren vom Allokator nicht zwangsläufig nothrow sein muss.
    (Oder das zerstören der Feldelemente)

    Wenn ein Destruktor wirft, wird das Programm ohnehin terminiert (oder schlimmeres). Deswegen muss man diesen Fall nicht behandeln.

    Ach!
    Ganz vergessen. Natürlich. Kopf->Tisch

    Sofort.

    P.S.: Und Danke für den Tipp mit Github, mach ich sofort!


  • Mod

    Sone schrieb:

    Schwierige Sache, da schon im Dtor das deallokieren vom Allokator nicht zwangsläufig nothrow sein muss.

    Die Deallokation darf nicht werfen (17.6.3.5/Table 28), Exceptions können folglich nur von Destruktoren stammen. Und mit Exceptions aus Destruktorn umgehen zu wollen, ist sowieso zum Scheitern verurteilt.



  • camper schrieb:

    Sone schrieb:

    Schwierige Sache, da schon im Dtor das deallokieren vom Allokator nicht zwangsläufig nothrow sein muss.

    Die Deallokation darf nicht werfen (17.6.3.5/Table 28)

    Schon vor dir gefunden 😃

    , Exceptions können folglich nur von Destruktoren stammen. Und mit Exceptions aus Destruktorn umgehen zu wollen, ist sowieso zum Scheitern verurteilt.

    Wenn du es sagst.
    noexcept -Spezifikationen hinzugefügt.

    Noch was?





  • So, jetzt geht alles. Code ist auf GitHub. ( ➡ Header "Dynarray.hxx")

    Eine Sache verstehe ich nur nicht:

    vom Allokator (privat) ableiten zwecks EBO

    Soll ich vom Allokator ableiten, oder wie soll ich das verstehen?



  • Das häufige Wechseln zwischen public und private macht die Klasse unübersichtlich.
    Tests wären auch nicht schlecht.
    Warum die exotische Endung .hxx ?
    Warum verschiedene Namensschemata? Ich sehe mindestens drei: my_iterator_traits , Dynarray , _constructWith

    camper schrieb:

    9. noexcept für Destruktor, move-Konstruktor/Zuweisung etc.

    Der Destruktor ist implizit noexcept(true) .


  • Mod

    TyRoXx schrieb:

    Der Destruktor ist implizit noexcept(true) .

    oh?

    Sone schrieb:

    Soll ich vom Allokator ableiten, oder wie soll ich das verstehen?

    Genau. Alternativ könnte auch eine Hilfsklasse verwendet werden, die alle Datenmember aufnimmt.



  • Ein dynarray mit nem Allocator macht doch überhaupt keinen Sinn ...?
    Weiters macht dynarray auch keinen Sinn so lange der Compiler es nicht versteht die Speicherallokation im Falle des Falles in ein alloca umzuwandeln.
    Ohne diesen Vorteil ist dynarray nämlich ein vollkommen sinnfreier Container.



  • TyRoXx schrieb:

    Das häufige Wechseln zwischen public und private macht die Klasse unübersichtlich.

    Done.

    Dazu jetzt noch mehr Kommentare für die Helfer-Funktionen.



  • camper schrieb:

    TyRoXx schrieb:

    Der Destruktor ist implizit noexcept(true) .

    oh?

    Ich glaube, TyRoXx verwechselt da den Dtor mit Deallokationsfunktionen. Den zu Dtors mit impliziter noexcept -Spezifikation habe ich nicht gefunden, aber mehrmals das hier:

    N3337 §12.5 / 9 schrieb:

    If a deallocation function has no explicit exception-specification, it is treated as if it were specified
    with noexcept(true)



  • Sone schrieb:

    TyRoXx schrieb:

    Warum verschiedene Namensschemata? Ich sehe mindestens drei: my_iterator_traits , Dynarray , _constructWith

    Für verschachtelte Klassen nehme ich die erste Benennung. Für ganz gewöhnliche Klassen(-templates) nehme ich UpperCamelCase, und für private Hilfsfunktionen nehme ich lowerCamelCase mit einem Unterstrich davor.

    unabhaengig von der Sinnhaftigkeit davon: deine Namensgebung ist nicht einheitlich.
    zB _destroy_all und _deallocateAll

    Check nochmal dein Aufraeumen wenn beim kopieren/initialisieren eine Exception fliegt. _destroy_all sieht da fehlerhaft aus.

    Nebenbei bemerkt: du verlangst dass die itertoaren auch verringert werden duerfen - was nicht unbedingt notwendig ist.

    Ich wuerde die einzelnen Methoden weiters noch per assert schuetzen. Und natuerlich um iterator debugging erweitern.



  • Hmm... begin/end ist noexcept ... rbegin/rend aber nicht.



  • Und ich muss nochmal nachfragen:

    Dynarray& operator=(Dynarray const& tmp)
        {
            Dynarray d(tmp);
            swap(d);
            return *this;
        }
    

    Warum recyclest du hier keinen Speicher? Das ist trivial umsetzbar und macht in der Praxis einen Unterschied.
    Solange der aktuelle allozierte Speicher ausreicht gibt es keinen Grund ihn freizugeben und neuen zu allozieren.



  • Ethon schrieb:

    Solange der aktuelle allozierte Speicher ausreicht gibt es keinen Grund ihn freizugeben und neuen zu allozieren.

    Doch. Man kann dann keine starke Exception-Garantie mehr geben.


  • Mod

    Sone schrieb:

    camper schrieb:

    TyRoXx schrieb:

    Der Destruktor ist implizit noexcept(true) .

    oh?

    Ich glaube, TyRoXx verwechselt da den Dtor mit Deallokationsfunktionen.

    Nicht unbedingt.

    n3337 schrieb:

    12.4 Destructors [class.dtor]
    [...]
    3 A declaration of a destructor that does not have an exception-specification is implicitly considered to have
    the same exception-specification as an implicit declaration (15.4).

    Die Exceptionspezifikation eines implizit deklarierten Destruktors hängt von den Exceptionsspezifikationen der Funktionen ab, die von diesem aufgerufen würden, d.h. den Destruktoren der Member und der direkten oder virtuellen Basisklassen. Wenn keiner dieser Destruktoren direkt oder indirekt eine explizite Exceptionspezifikation erhält, läuft das somit tatsächlich im Allgemeinen auf eine Sepzifikation noexcept(true) hinaus.
    Die Exceptionspezifikation ist mAn Teil der Schnittstelle und sollte somit nicht implizit von privaten Details der Klasse abhängen - deshalb halte ich eine explizite Angabe für sinnvoll. Der Standard macht es anders, man kann also durchaus auch andere Ansicht sein.



  • Lol, 5 Seiten Ratschläge und es funktioniert immer noch nicht.
    Abgesehen von den Warnungen, wenn man deinen Code kompiliert (schonmal mit -Wall -Wextra getestet?), es hat noch einige Bugs.

    Hier mal ein einfaches Testprogramm:

    int instances = 0;
    
    void may_throw()
    {
      if (rand()%100 == 0)
        throw 0;
    }
    
    struct test {
      test() { ++instances; may_throw(); }
      test(test const&) { ++instances; may_throw(); }
     ~test() { --instances; }
    };
    
    int main()
    {
      srand(0);
    
      try { Dynarray<test> d(1000); }
      catch (...) {}
    
      std::cout << instances << '\n';
    }
    

    Wenn Zeile 12 etwas abändert, dürfte der Fehler etwas klarer werden.

    ~test() { std::cout << --instances << '\n'; }
    

Anmelden zum Antworten