Haben diese Defines irgendeinen Sinn?



  • Hallo, ob des akuten Frustes über einen Quellcode den ich neuprogrammieren darf (da der alte unfassbar grausam schlecht ist, kA wer den verbrochen hat):

    Hat das hier IRGENDEINEN praktischen Sinn?!

    #define	_new(t)			((t*)malloc(sizeof(t)))
    #define	_new_array(t, n)	((t*)malloc(sizeof(t) * (n)))
    #define	_resize_array(a, t, n)	((t*)realloc((a), sizeof(t) * (n)))
    #define _size_array(a,t,n0,n1)  a = (n0 == 0 ? _new_array(t,n1) : \
                                                   _resize_array(a,t,n1))
    #define	_delete(object)		((void)(((object)!=NULL) ? \
    				    free((char*)(object)),(object)=NULL : 0))
    

    Natürlich genuzt in deinem C++-Projekt...

    Gott macht mich das grade wütend



  • std::vector, std::unique_ptr



  • reine Schikane, Stichwort Job-Security



  • An einer Uni? Glaub ich nicht so recht 😃



  • Wenn man sich ganz arg bemüht könnte man darin einen aufrichtigen Versuch sehen, diese malloc/free in ein C++-ähnlicheres Interface packen. Das ermöglicht es den cast zu vermeiden. Gleichzeitig ermöglicht es C-Komponenten die Zeiger zu löschen.

    Aber ehrlich, nicht einmal das wird richtig gemacht:
    - Die checks auf 0 sind völlig überflüssig
    - Die Namen sind für die Implementation reserviert.
    - Man kann auch new/delete so überschreiben, dass die malloc/free verwenden
    Besonders lustig ist das verpönte Zeiger nach delete auf NULL setzen

    Dafür habe ich nur ein riesiges looool übrig, solchen Code kann man nicht fixen, da hilft nur neuschreiben.



  • Mit viel gutem Willen könnte man vermuten dass es ein äußerst miserabler Versuch war den Code zwischen C und C++ kompatibel zu halten.



  • loool schrieb:

    Wenn man sich ganz arg bemüht könnte man darin einen aufrichtigen Versuch sehen, diese malloc/free in ein C++-ähnlicheres Interface packen. Das ermöglicht es den cast zu vermeiden. Gleichzeitig ermöglicht es C-Komponenten die Zeiger zu löschen.

    Aber ehrlich, nicht einmal das wird richtig gemacht:
    - Die checks auf 0 sind völlig überflüssig
    - Die Namen sind für die Implementation reserviert.
    - Man kann auch new/delete so überschreiben, dass die malloc/free verwenden
    Besonders lustig ist das verpönte Zeiger nach delete auf NULL setzen

    Dafür habe ich nur ein riesiges looool übrig, solchen Code kann man nicht fixen, da hilft nur neuschreiben.

    Das Neuschreiben fällt nun ja auch mir (und noch wem anderes) zu 😕
    Nur unfassbar anstrengend, wenn man den theoretischen Hintergrund nicht kennt und daher erstmal nachvollziehen muss was so ein Code denn tut. Der ganze Code sieht praktisch so aus wie das Beispiel (also von der Qualität her).
    BRRR 😞


  • Mod

    Die Namen sind für die Implementation reserviert.

    Nein, das sind sie nicht. Nicht jeder Name, der mit einem Unterstrich beginnt, ist reserviert.

    Mit viel gutem Willen könnte man vermuten dass es ein äußerst miserabler Versuch war den Code zwischen C und C++ kompatibel zu halten.

    Und wie ist das Fehler-Behandeln geregelt?



    • schrieb:

    Die Namen sind für die Implementation reserviert.

    Nein, das sind sie nicht. Nicht jeder Name, der mit einem Unterstrich beginnt, ist reserviert.

    *facepalm*


  • Mod

    Ist natürlich Unsinn.
    Vor allem, weil es sogar genauso definiert ist:

    Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.


  • Mod

    • schrieb:

    Und wie ist das Fehler-Behandeln geregelt?

    Man könnte für C++ das Makro natürlich so definieren

    #define _new(T) new (std::nothrow_t)T
    

    Allerdings ist das ab dem Punkt Blödsinn, wo nicht triviale Klassen im Spiel sind.
    In C gibt es das natürlich nicht. Nun, dann klappt das sogar.



    • schrieb:

    Ist natürlich Unsinn.

    Der grösste Unsinn ist, dass du ständig den Inhalt deiner Posts völlig umänderst. Das regt mich auf. Das ist unredlich, wie jemand anders mal gesagt hat.

    Wenn du was geschrieben hast, warte 10sec bevor du den Absenden-Button drückst und frage dich, ob das Sinn macht, was du schreibst.

    Wenn du erst im Nachhinein merkst, dass das Schwachsinn ist, dann lass den Text, aber streich ihn durch.

    Im Editieren ist nur einer der folgenden Züge erlaubt:
    1. Ortographiefehler beheben.
    2. Sachen durchstreichen.
    3. Ganz am Schluss ein "Edit: <neuer Text>" hinzufügen.
    Halte dich mal eine Woche oder so ausnahmslos dran.

    Irren ist menschlich, aber steh zu deinen Fehlern. So führt das nur zu Diskussionen, die nicht nachvollziehbar sind.


  • Mod

    Gut, das nehme ich mir vor - Post ist gestrichen.

    Irren ist menschlich, aber steh zu deinen Fehlern.

    Das stand da buchstäblich mehrere Sekunden!



  • Hallo, ob des akuten Frustes über einen Quellcode den ich neuprogrammieren darf (da der alte unfassbar grausam schlecht ist, kA wer den verbrochen hat):

    Hat das hier IRGENDEINEN praktischen Sinn?!

    C++:
    #define _new(t) ((t*)malloc(sizeof(t)))
    #define _new_array(t, n) ((t*)malloc(sizeof(t) * (n)))
    #define _resize_array(a, t, n) ((t*)realloc((a), sizeof(t) * (n)))
    #define _size_array(a,t,n0,n1) a = (n0 == 0 ? _new_array(t,n1) : \
    _resize_array(a,t,n1))
    #define _delete(object) ((void)(((object)!=NULL) ? \
    free((char*)(object)),(object)=NULL : 0))

    Natürlich genuzt in deinem C++-Projekt...

    Gott macht mich das grade wütend

    Für mich macht solchen Code keine Sinn, außer dass ein C Programmierer versucht C++ zu programmieren.

    Der Code strotzt vor Fehlerquellen / Seiteneffekten uns sollte verbessert werden.

    Und bitte: Keine Makro's!!!



  • @Bitte ein Bit
    > Und bitte: Keine Makro's!!!

    Wieso nicht?

    Makros sind doch in C perfekt dafür. Bzw. die einzige Möglichkeit - Templates gibt's ja nicht. Worüber man streiten kann sind die Seiteneffekte.
    Andrerseits hast du die in C++ genau so, wenn irgendwo mit "non-const" Referenzen wird.



  • Makros sind doch in C perfekt dafür. Bzw. die einzige Möglichkeit - Templates gibt's ja nicht.

    Ja in C vieleicht. Aber selbst hier würde ich nur ganz einfache Makro's benutzen, weil diese unter anderem nicht debugbar sind.

    Da wir hier aber in der C++ Abteilung sind, stellt sich hier nicht die Frage nach C.

    Worüber man streiten kann sind die Seiteneffekte.

    #define _new(t) ((t*)malloc(sizeof(t)))
    #define _new_array(t, n) ((t*)malloc(sizeof(t) * (n)))
    #define _resize_array(a, t, n) ((t*)realloc((a), sizeof(t) * (n)))
    #define _size_array(a,t,n0,n1) a = (n0 == 0 ? _new_array(t,n1) : \
    _resize_array(a,t,n1))
    #define _delete(object) ((void)(((object)!=NULL) ? \
    free((char*)(object)),(object)=NULL : 0)) 
    
    #define _resize_array2(a, t, n) (realloc((a), sizeof(t) * (n)))
    class A
    {
        int a;
    public:
        A() : 
          a(-1)
        {}
    };
    int main(int argc, char** argv)
    {
        A* MyA;
        char* a;
        unsigned char NewSize = 5;
    
        // Warum ist hier MyA() nicht -1???
        MyA = _new(A);
        // Was mache ich hier falsch? Und wie debugge ich das?
        _size_array(a, char, 0, 5) + 1;
        (_size_array(a, char, 0, 5)) = 0;
        _resize_array2(a, 2, 5);
        _size_array(a, char, 3, 5) + 1;
        _size_array(a, char, 3, ++NewSize) + 1;  // Der Klassiker unter den Beispielen!
        return 0;
    }
    

    Wie du oben siehst, ist es mit diesen Makro Funktionen relativ leicht schwer auffindbare Fehler zu produzieren. Bekomme das mal mit std::vector hin!

    Spiel doch einfach mal destruktiver DAU und versuche den Code zum Absturz zu bewegen!

    Andrerseits hast du die in C++ genau so, wenn irgendwo mit "non-const" Referenzen wird.
    

    Wären wir hier bei Templates würde ich davon sprechen das die Typsicherheit als auch das Konzept (Bsp.: DefaultConstructible) fehlt.

    Wir sollten mal einen kleinen Wettbewerb versuchen. Wir sollten eine einfache Aufgabe mittels Makro und (inline) Funktion lösen und jeweils versuchen sie einfach und sicher bedienbar zu machen, s.d. bei allen Eingaben immer etwas sinnvolles herauskommt.

    Wetten: Makros unterliegen?


  • Mod

    Bitte ein Bit: Das habe ich oben bereits festgestellt, dass das bei Klassen* in C++ nicht funktioniert. Es ist sogar undefiniertes Verhalten, mit dem gecasteten Zeiger irgendwelche Memberfunktionen aufzurufen o.ä.

    Edit:

    Da wir hier aber in der C++ Abteilung sind, stellt sich hier nicht die Frage nach C.

    Offensichtlich ist aber der Code (für oder mit) C geschrieben. Mit Klassen* darf man das nicht mischen.

    • ~mit nicht-trivialen Klassen.~


  • Bitte ein Bit schrieb:

    Makros sind doch in C perfekt dafür. Bzw. die einzige Möglichkeit - Templates gibt's ja nicht.

    Ja in C vieleicht. Aber selbst hier würde ich nur ganz einfache Makro's benutzen, weil diese unter anderem nicht debugbar sind.

    Das ist ja auch ganz eindeutig C Code.

    Wir sollten eine einfache Aufgabe mittels Makro und (inline) Funktion lösen und jeweils versuchen sie einfach und sicher bedienbar zu machen, s.d. bei allen Eingaben immer etwas sinnvolles herauskommt.

    Wetten: Makros unterliegen?

    Wenn ich die Anforderungen festlegen kann dann gewinnen sicher Makros, weil ich dann nämlich Sachen auswähle die man mit Inline-Funktionen einfach nicht (oder nicht sinnvoll) machen kann 😉
    Deren gibt es in C extrem viele, aber auch in C++ ist noch einiges übrig.



  • Das ist ja auch ganz eindeutig C Code.

    Das _new() Makro sieht aber ein wenig nach C/C++ Mischmasch aus. Ein C Programmierer würde nämlich den Cast nach (t*) weglassen. Unter C++ wirft mein Compiler mir einen Fehler um die Ohren. 😉

    #define _new(t)         ((t*)malloc(sizeof(t)))
    

    Wenn ich die Anforderungen festlegen kann dann gewinnen sicher Makros, weil ich dann nämlich Sachen auswähle die man mit Inline-Funktionen einfach nicht (oder nicht sinnvoll) machen kann

    Kannst du mir mal ein Beispiel geben?



  • Bitte ein Bit schrieb:

    Wenn ich die Anforderungen festlegen kann dann gewinnen sicher Makros, weil ich dann nämlich Sachen auswähle die man mit Inline-Funktionen einfach nicht (oder nicht sinnvoll) machen kann

    Kannst du mir mal ein Beispiel geben?

    Logging.


Log in to reply