Anfängerfrage wegen Klasse



  • Singender Holzkübel schrieb:

    hustbaer schrieb:

    Singender Holzkübel schrieb:

    2D Array Source, schnell und hässlich.

    Was soll dieser Kot?
    Damit kannst du uns nur beweisen wie wenig Ahnung du von irgendwas hast.

    Wenn du meinst dass du so kuhl bist, dann poste etwas was es wenigstens wert ist dass wir uns die Sache mal genauer ansehen -- und dann auseinandernehmen.

    You must be new to this thread.

    You must be new to C++.



  • asfdlol schrieb:

    Singender Holzkübel schrieb:

    asfdlol schrieb:

    Singender Holzkübel schrieb:

    2D Array Source, schnell und hässlich.

    ist ein 1d-array und ausserdem ist der code nicht exceptionsicher. hättest du bloss auf uns gehört... 🙄

    Der Sinn von Exceptions ist, dass man sie fangen kann.
    C++-syntaxisch ist es 1D. Mehrdimensionale Arrays sind Syntax Sugar.

    :D?????????????????

    bin ich hier der dumme wenn ich das nicht verstehe?

    Was verstehst du nicht?
    Exceptions kann man fangen/muss man aber nicht (Java verhält sich da ein bisschen anders. Dort muss man sie wenigstens manuell weiter werfen quasi durch throws), wie schlau oder dumm das ist, steht auf dem Blatt der Anforderungen und des Designs und kommt vor allem auf den Fehler an.

    Mehrdimensionale Arrays ála int a[n][n] ja sind schon etwas Syntactic Sugar. Aber die spezifische Semantik ist eine andere als bei int * a[], wobei jeder Zeiger mit einem weiteren Array initialisiert wird. Umgekehrt ist der Index-Zauber wieder gleich int a[n][n].
    Der Unterschied liegt in der Art wie die Daten im Speicher liegen.

    int * a[] = new int*[n];
    for(int i = 0; i < n; i++)
        a[i] = new int[n];
    

    Hier liegen irgendwo im Speicher in Zusammenhängender Form n Zeiger. Jeder Zeiger zeigt irgendwohin im Speicher auf n Integers. Das muss nicht zusammenhängend sein (wirds meistens auch nicht), kann es aber in seltenen Fällen.

    int a[n][n];
    int a[n*n];
    

    Hierbei gibt es einen großen Speicherblock der in beiden Fällen n*n Ints groß ist: es liegen nämlich n Speicherblöcke der Größe n hintereinander. Wie Holzkübel schon sagte, das ist Syntax Zucker.

    Während die erste Möglichkeit zwar eher funktioniert, wenn Speicher knapp wird, haben die beiden letzteren Möglichkeiten den immensen Vorteil der Ausnutzung des Caches. (Was nicht heisst, dass je nach Zahlen für n eine der beiden Arten besser oder schlechter ist. Wenn n die Cachelinegröße ist kommt auch die erste Möglichkeit ganz gut hin.)
    Denn willst du alle Speicherplätze des Arrays mal anfassen (lesen/schreiben), wird deine CPU sich bei kleinen n's das gesamte Array auf einmal in den Cache holen ohne nochmal den Hauptspeicher anfassen zu müssen. Bei der Doppelpointer Geschichte wird er alle n Zugriffe neue Anfragen an den RAM stellen müssen und im Normalfall wird die Differenz zwischen n und der Cachelinegröße an Daten nie benutzt (aber trotzdem mitgeladen) und daher verworfen.



  • Nathan schrieb:

    asfdlol schrieb:

    was ist das hier eigentlich?

    if(aeiou) delete[] aeiou;
    

    Hab ich gar nicht gesehen.
    Man ergänze noch eine Zeile:

    if(aeiou)
    {
      delete[] aeiou;
      aeiou = nullptr;
    }
    

    Und schon hat man ein perfektes Negativbeispiel für Speicherfreigabe.
    2 Dinge:
    1. delete[] kommt mit nullptr klar.
    2. Wieso sollte aeiou 0 sein?

    1. Ok das ist neu für mich.
    2. Das ist bei mir mittlerweile Gewohnheit.

    Ich programmiere wohl zu viel C.


  • Mod

    Singender Holzkübel schrieb:

    Ich programmiere wohl zu viel C.

    In C ist das nicht anders.



  • Woher kommt/kam dieser Mythos eigentlich, dass man vorm deleten/freen erstmal einen Nullcheck macht?

    ich kenen ein paar Bücher wo es sowas in der Art gibt:

    #define SAFE_DELETE(x) if ( (x) ) delete (x);
    #define SAFE_DELETE_ARRAY(x) if ( (x) ) delete[] (x);
    

    Aber wieso?



  • SeppJ schrieb:

    Singender Holzkübel schrieb:

    Ich programmiere wohl zu viel C.

    In C ist das nicht anders.

    Mind == blown
    ~Sarcasm not intended~

    Skym0sh0 schrieb:

    Woher kommt/kam dieser Mythos eigentlich, dass man vorm deleten/freen erstmal einen Nullcheck macht?

    Das interessiert mich jetzt auch.



  • Skym0sh0 schrieb:

    Woher kommt/kam dieser Mythos eigentlich, dass man vorm deleten/freen erstmal einen Nullcheck macht?

    ich kenen ein paar Bücher wo es sowas in der Art gibt:

    #define SAFE_DELETE(x) if ( (x) ) delete (x);
    #define SAFE_DELETE_ARRAY(x) if ( (x) ) delete[] (x);
    

    Aber wieso?

    Weil Du schlechte Bücher kaufst? Weil Amazon-Rezensionen bei der Auswahl von Fachbüchern antihilfreich sind?

    SAFE_DELETE baut jemand, der seine Programmierfehler nicht jagt und vernichtet, sondern lieber versteckt und schimmeln läßt. Es geht darum, stets die Übersicht darüber zu verlieren, ob man seine Objekte gelöscht hat. Nicht "Ein new gehört zu einem delete" zu befolgen. Na, dann haut man, wo man unsicher ist, noch ein paar SAFE_DELETE rein, die übrigens selber x auf 0 setzen, vollständig vielleicht so heißen:

    #define SAFE_DELETE(x) if ( (x) ) { delete (x); (x) = NULL; } else ;
    #define SAFE_DELETE_ARRAY(x) if ( (x) ) { delete[] (x); (x) = NULL; } else ;
    

    und deswegen ruhig mehrfach auf den selben Zeiger losgelassen werden können.

    Mir ist schon passiert, daß mich ein Gamecoder, der mir nachweisen wollte, daß er besser als ich C++ kann, fragte, wie man safe_delete richtig implemetiert. Er wollte eine Funktion mit Template und Referenz auf Zeiger haben.


  • Mod

    Skym0sh0 schrieb:

    Woher kommt/kam dieser Mythos eigentlich, dass man vorm deleten/freen erstmal einen Nullcheck macht?

    Man kann dafür Argumente finde, die haben allerdings absolut nichts mit Sicherheit zu tun
    - unter bestimmten Umständen kann es zu besserem Code führen (die Aussage, dass delete auf 0 keine Effekt hat bedeutete vor C++11 nicht, dass der Compiler den Aufruf der Deallokationsfunktion einfach eleminieren durfte)
    - delete auf 0 hebt die Paarigkeit zwischen new und delete gerade auf, und das Argument, dass delete damit zurecht kommt, kann man auch umdrehen: warum überhaupt einen sinnlosen Funktionsaufruf durchführen?
    Das sind keine besonders starken Argumente und ganz sicher keine, die die Einführung eines Makros rechtfertigen.

    #define SAFE_DELETE(x) if ( (x) ) delete (x);
    #define SAFE_DELETE_ARRAY(x) if ( (x) ) delete[] (x);
    

    Eine SAFE_DELETE, wenn man meint, so etwas zu brauchen, sollte zumindest gegen die eigentliche Falle bei delete absichern: das Löschen von Objekten mit unvollständigem Typ, die gezeigten Makros tun das nicht.



  • Skym0sh0 schrieb:

    Woher kommt/kam dieser Mythos eigentlich, dass man vorm deleten/freen erstmal einen Nullcheck macht?

    Wieso Mythos? Wenn man nicht weiß, dass free/operator delete mit einem Nullpointer klarkommen, ist das automatisch.

    ich kenen ein paar Bücher wo es sowas in der Art gibt

    In Büchern ist das natürlich peinlich, die sollten von Leuten geschrieben werden, die es besser wissen.

    Die Idee, dass man danach den Zeiger auf Null setzen sollte, wie das Volkard vorführt, die dagegen entsteht aus echtem Unverständnis.



  • Oh Mann!
    Die immerwährende unsachliche Diskussion in diesem Forum um das Thema "C++ und Objekterstellung auf dem Heap" hinterlässt bei mir den Beigeschmack von religiösem Eifer wie zu Zeiten der Inquisition. Ich würde mich in diesem Forum als Novize gar nicht mehr trauen, nach "new" und "delete" zu fragen bei so viel Polemik und Flame.
    Und selbstverständlich kündige ich nicht meinen Job, wenn mein Arbeitgeber z.Z. einen älteren Compiler einsetzt oder ich eine alte Software mit diesem warten soll. Und natürlich kann und muss ich auch mit dem Heap umgehen.
    Sachdienlicher sind die Beiträge von Forumsteilnehmern, welche eine Frage zur Speicherverwaltung sachlich beantworten und ggf. nur auf eine Verbesserung wie z.B. 'Smart Pointer' hinweisen, bzw. vorschlagen.



  • Helmut.Jakoby schrieb:

    Die immerwährende unsachliche Diskussion in diesem Forum um das Thema "C++ und Objekterstellung auf dem Heap" hinterlässt bei mir den Beigeschmack von religiösem Eifer wie zu Zeiten der Inquisition. Ich würde mich in diesem Forum als Novize gar nicht mehr trauen, nach "new" und "delete" zu fragen bei so viel Polemik und Flame.

    Das stimmt aber so nicht:

    Ich als Novize sehe das mittlerweile so:

    i) Möchtest du neuen Code von Grund auf in C++11/14 schreiben, dann gibt es bestimmt zunächst keine Grund new / delete zu verwenden.(*)

    ii) Musst du allerdings manuell Speicher verwalten, weil du z.B. eine C Bibliothek einbinden musst, wie das bei mir schon öfter der Fall war und ist, dann wird dir hier doch sehr ordentlich geholfen.

    (*) Falls der Ausgangspunkt des Gezankes wirklich der 2D Array des Eingangsposts war, dann ist sicherlich ein 'nested std::vector ' besser als jedes verschachteln von dynamisch angelegten Arrays.
    Dann bist du die manuelle Speicherwaltung direkt los.

    Gruß,
    -- Klaus.


  • Mod

    Klaus82 schrieb:

    i) Möchtest du neuen Code von Grund auf in C++11/14 schreiben, dann gibt es bestimmt zunächst keine Grund new / delete zu verwenden.(*)

    Mach daraus C++98, dann passt das. So viel übrigens auch zu Helmuts "älteren Compilern". Diese Compiler sind mittlerweile älter als ein frisch ausgebildeter Programmierer.



  • Helmut.Jakoby schrieb:

    Oh Mann!
    Die immerwährende unsachliche Diskussion in diesem Forum um das Thema "C++ und Objekterstellung auf dem Heap" hinterlässt bei mir den Beigeschmack von religiösem Eifer wie zu Zeiten der Inquisition. Ich würde mich in diesem Forum als Novize gar nicht mehr trauen, nach "new" und "delete" zu fragen bei so viel Polemik und Flame.

    Keiner hat was gegen "Objekterstellung auf dem Heap". Der Heap ist super.
    Wir haben nur etwas gegen manuelle Speicherverwaltung, weil die eben manuell ist.

    Und selbstverständlich kündige ich nicht meinen Job, wenn mein Arbeitgeber z.Z. einen älteren Compiler einsetzt oder ich eine alte Software mit diesem warten soll. Und natürlich kann und muss ich auch mit dem Heap umgehen.

    RAII gibt es schon seit Anbeginn von C++...



  • Nathan schrieb:

    RAII gibt es schon seit Anbeginn von C++...

    Und für manche ist es auch DER Grund C++ zu nutzen oder so geil zu finden.

    Wenn du es halbwegs richtig nutzt, kannst du dafür sorgen, dass bestimmte Dinge niemals vergessen werden:

    template<class In, class Ex>
    class raii_object
    {
    	In begin;
    	Ex exit;
    
    public:
    	raii_object(In && i, Ex && e) : begin(i), exit(e) { begin(); }
    	~raii_object() { exit(); }
    
    	raii_object(raii_object const&) = delete;
    	raii_object(raii_object &&) = delete;
    	raii_object& operator=(raii_object) = delete;
    	raii_object& operator=(raii_object&&) = delete;
    };
    
    template<class In, class Ex>
    raii_object<In, Ex> make_raii_object(In i, Ex e)
    {
    	return raii_object(i, e);
    }
    
    int main()
    {
    	auto enforcer = make_raii_object(
    		[](){ cout << "Begin: "; },
    		[](){ cout << "End."; }
    	);
    
    	// do shit
    	if ( x == 0 )
    		return -1;
    	// else do further shit
    	if ( x == 0 )
    		throw std::exception("Ausgabe wird trotzdem erledigt.");
    	// ...
    	return 0;
    }
    

    (Kopier/Move Semantik mal außen vorlassen, die ist hier nicht teil des Themas)

    Egal, was in diesem Programm passiert. Die "End"-Ausgabe wird auf jedenfall stattfinden,ohne dass ich weiteres schreiben muss oder Fälle unterscheiden muss bei verschiedenen Austritsspunkten.



  • camper schrieb:

    Skym0sh0 schrieb:

    Woher kommt/kam dieser Mythos eigentlich, dass man vorm deleten/freen erstmal einen Nullcheck macht?

    Man kann dafür Argumente finde, die haben allerdings absolut nichts mit Sicherheit zu tun
    - unter bestimmten Umständen kann es zu besserem Code führen (die Aussage, dass delete auf 0 keine Effekt hat bedeutete vor C++11 nicht, dass der Compiler den Aufruf der Deallokationsfunktion einfach eleminieren durfte)

    Unter Umständen kann ein Schwein auch fliegen.
    Du müsstest diese Aussage erst einmal belegen und mir dann noch erklären warum Programmierer, die von sonst nichts einen Plan haben, ausgerechnet bei delete zu Mikrooptimierungsgenies werden sollen.

    camper schrieb:

    - delete auf 0 hebt die Paarigkeit zwischen new und delete gerade auf, und das Argument, dass delete damit zurecht kommt, kann man auch umdrehen: warum überhaupt einen sinnlosen Funktionsaufruf durchführen?

    Es gibt keine Paarigkeit zwischen new und delete . new wurde wahrscheinlich vor den Referenzen eingeführt, also gibt es bis heute einen Zeiger zurück. Das gleiche gilt im Prinzip für delete . Weil delete einen Zeiger nehmen musste, konnte man auch gleich die Semantik von free übernehmen, auch um C-Programmierern den Umstieg leichter zu machen. free kommt aus zwei Gründen mit Nullzeigern klar:
    1. Es kann den Clean-Up-Teil von Funktionen vereinfachen.
    2. Es spart dabei Verzweigungsinstruktionen und damit Speicher.

    Mal abgesehen davon, dass jedes Vorkommen vom delete -Schlüsselwort ein Bug ist, gibt es ganz banale Argumente gegen das redundante if :
    - es ist mehr Schreibarbeit
    - es ist mehr Lesearbeit
    - es ist hässlich
    - es ist nicht schneller

    Der typische Fall ist doch, dass der Zeiger nicht null ist. Warum also für den Fall optimieren, dass der null ist? Man verwirrt den Prozessor mit der Verzweigung nur. Ein Aufruf einer konstanten Funktion wie delete ist auch gar nicht teuer. Die delete -Funktion wird in den meisten Programme ohnehin sehr häufig aufgerufen, also spart man wahrscheinlich nicht einmal Instruction Cache, wenn man die Aufrufe meidet. Moderne Prozessoren würden vielleicht sogar spekulativ das if und das zugehörige delete gleichzeitig ausführen. Dann hätte man nur Zeit verschwendet. Außerdem weiß man beim Programmieren in C++ gar nicht mit welchem Prozessor man es mal zu tun haben könnte. Es kann gut sein, dass das if auf dem einen Prozessor minimal Zeit spart, aber auf dem anderen die Ausführung stark verlangsamt. Die Unterschiede bei so etwas sind zwischen Prozessormodellen oft riesig, zum Beispiel Atom vs i7. Die sind beide von Intel und fressen denselben Code, unterscheiden sich aber stark bei internen Optimierungen wie out of order execution, was hier eine Rolle spielen kann.
    Kurz: Das mit der Optimierung ist Unsinn.

    Es kann natürlich sein, dass Profiling auf einer Hardware dem if in einem konkreten Programm einen Vorteil bescheinigt. Dann kann man so etwas machen:

    #include <memory>
    
    template <class T>
    struct optimized_deleter
    {
    	void operator ()(T *p) const
    	{
    #ifdef PROCESSOR_ARCHITECTURE_XY
    		//benchmark 53 shows that this is a bit faster in most cases ...
    		if (!p)
    		{
    			return;
    		}
    #endif
    		delete p;
    	}
    };
    
    int main()
    {
    	std::unique_ptr<int, optimized_deleter<int>> p(new int(1));
    	auto q = std::move(p);
    }
    


  • TyRoXx schrieb:

    camper schrieb:

    Skym0sh0 schrieb:

    Woher kommt/kam dieser Mythos eigentlich, dass man vorm deleten/freen erstmal einen Nullcheck macht?

    Man kann dafür Argumente finde, die haben allerdings absolut nichts mit Sicherheit zu tun
    - unter bestimmten Umständen kann es zu besserem Code führen (die Aussage, dass delete auf 0 keine Effekt hat bedeutete vor C++11 nicht, dass der Compiler den Aufruf der Deallokationsfunktion einfach eleminieren durfte)

    Unter Umständen kann ein Schwein auch fliegen.
    Du müsstest diese Aussage erst einmal belegen und mir dann noch erklären warum Programmierer, die von sonst nichts einen Plan haben, ausgerechnet bei delete zu Mikrooptimierungsgenies werden sollen.

    camper schrieb:

    - delete auf 0 hebt die Paarigkeit zwischen new und delete gerade auf, und das Argument, dass delete damit zurecht kommt, kann man auch umdrehen: warum überhaupt einen sinnlosen Funktionsaufruf durchführen?

    Es gibt keine Paarigkeit zwischen new und delete . new wurde wahrscheinlich vor den Referenzen eingeführt, also gibt es bis heute einen Zeiger zurück. Das gleiche gilt im Prinzip für delete . Weil delete einen Zeiger nehmen musste, konnte man auch gleich die Semantik von free übernehmen, auch um C-Programmierern den Umstieg leichter zu machen. free kommt aus zwei Gründen mit Nullzeigern klar:
    1. Es kann den Clean-Up-Teil von Funktionen vereinfachen.
    2. Es spart dabei Verzweigungsinstruktionen und damit Speicher.

    Mal abgesehen davon, dass jedes Vorkommen vom delete -Schlüsselwort ein Bug ist, gibt es ganz banale Argumente gegen das redundante if :
    - es ist mehr Schreibarbeit
    - es ist mehr Lesearbeit
    - es ist hässlich
    - es ist nicht schneller

    Der typische Fall ist doch, dass der Zeiger nicht null ist. Warum also für den Fall optimieren, dass der null ist? Man verwirrt den Prozessor mit der Verzweigung nur. Ein Aufruf einer konstanten Funktion wie delete ist auch gar nicht teuer. Die delete -Funktion wird in den meisten Programme ohnehin sehr häufig aufgerufen, also spart man wahrscheinlich nicht einmal Instruction Cache, wenn man die Aufrufe meidet. Moderne Prozessoren würden vielleicht sogar spekulativ das if und das zugehörige delete gleichzeitig ausführen. Dann hätte man nur Zeit verschwendet. Außerdem weiß man beim Programmieren in C++ gar nicht mit welchem Prozessor man es mal zu tun haben könnte. Es kann gut sein, dass das if auf dem einen Prozessor minimal Zeit spart, aber auf dem anderen die Ausführung stark verlangsamt. Die Unterschiede bei so etwas sind zwischen Prozessormodellen oft riesig, zum Beispiel Atom vs i7. Die sind beide von Intel und fressen denselben Code, unterscheiden sich aber stark bei internen Optimierungen wie out of order execution, was hier eine Rolle spielen kann.
    Kurz: Das mit der Optimierung ist Unsinn.

    Nö.


  • Mod

    TyRoXx schrieb:

    camper schrieb:

    Skym0sh0 schrieb:

    Woher kommt/kam dieser Mythos eigentlich, dass man vorm deleten/freen erstmal einen Nullcheck macht?

    Man kann dafür Argumente finde, die haben allerdings absolut nichts mit Sicherheit zu tun
    - unter bestimmten Umständen kann es zu besserem Code führen (die Aussage, dass delete auf 0 keine Effekt hat bedeutete vor C++11 nicht, dass der Compiler den Aufruf der Deallokationsfunktion einfach eleminieren durfte)

    Unter Umständen kann ein Schwein auch fliegen.
    Du müsstest diese Aussage erst einmal belegen und mir dann noch erklären warum Programmierer, die von sonst nichts einen Plan haben, ausgerechnet bei delete zu Mikrooptimierungsgenies werden sollen.

    Als Erstes zeigst du mir bitte, wo ich zu Mikrooptimierung aufgerufen habe. Und wenn du ein zutreffendes Beispiel haben möchtest, kannst du gerne danach fragen.

    TyRoXx schrieb:

    camper schrieb:

    - delete auf 0 hebt die Paarigkeit zwischen new und delete gerade auf, und das Argument, dass delete damit zurecht kommt, kann man auch umdrehen: warum überhaupt einen sinnlosen Funktionsaufruf durchführen?

    Es gibt keine Paarigkeit zwischen new und delete . new wurde wahrscheinlich vor den Referenzen eingeführt, also gibt es bis heute einen Zeiger zurück. Das gleiche gilt im Prinzip für delete . Weil delete einen Zeiger nehmen musste, konnte man auch gleich die Semantik von free übernehmen, auch um C-Programmierern den Umstieg leichter zu machen. free kommt aus zwei Gründen mit Nullzeigern klar:
    1. Es kann den Clean-Up-Teil von Funktionen vereinfachen.
    2. Es spart dabei Verzweigungsinstruktionen und damit Speicher.

    Mal abgesehen davon, dass jedes Vorkommen vom delete -Schlüsselwort ein Bug ist, gibt es ganz banale Argumente gegen das redundante if :
    - es ist mehr Schreibarbeit
    - es ist mehr Lesearbeit
    - es ist hässlich
    - es ist nicht schneller

    Der typische Fall ist doch, dass der Zeiger nicht null ist. Warum also für den Fall optimieren, dass der null ist? Man verwirrt den Prozessor mit der Verzweigung nur. Ein Aufruf einer konstanten Funktion wie delete ist auch gar nicht teuer. Die delete -Funktion wird in den meisten Programme ohnehin sehr häufig aufgerufen, also spart man wahrscheinlich nicht einmal Instruction Cache, wenn man die Aufrufe meidet. Moderne Prozessoren würden vielleicht sogar spekulativ das if und das zugehörige delete gleichzeitig ausführen. Dann hätte man nur Zeit verschwendet. Außerdem weiß man beim Programmieren in C++ gar nicht mit welchem Prozessor man es mal zu tun haben könnte. Es kann gut sein, dass das if auf dem einen Prozessor minimal Zeit spart, aber auf dem anderen die Ausführung stark verlangsamt. Die Unterschiede bei so etwas sind zwischen Prozessormodellen oft riesig, zum Beispiel Atom vs i7. Die sind beide von Intel und fressen denselben Code, unterscheiden sich aber stark bei internen Optimierungen wie out of order execution, was hier eine Rolle spielen kann.
    Kurz: Das mit der Optimierung ist Unsinn.

    Es kann natürlich sein, dass Profiling auf einer Hardware dem if in einem konkreten Programm einen Vorteil bescheinigt. Dann kann man so etwas machen:

    #include <memory>
    
    template <class T>
    struct optimized_deleter
    {
    	void operator ()(T *p) const
    	{
    #ifdef PROCESSOR_ARCHITECTURE_XY
    		//benchmark 53 shows that this is a bit faster in most cases ...
    		if (!p)
    		{
    			return;
    		}
    #endif
    		delete p;
    	}
    };
    
    int main()
    {
    	std::unique_ptr<int, optimized_deleter<int>> p(new int(1));
    	auto q = std::move(p);
    }
    

    Nö.

    Edit: ach nein, das hat volkard ja schon gesagt.


  • Mod

    Moderne Prozessoren würden vielleicht sogar spekulativ das if und das zugehörige delete gleichzeitig ausführen.

    delete resultiert doch in einem API-Aufruf? Oder steckt der Nullpointertest schon im operator delete drin? In letzterem Fall ist das if Überflüssig und wird einfach wegoptimiert (zweimal hintereinander denselben Wert von einer Variable abfragen). Wenn nicht, wird tatsächlich der Funktionsaufruf gespart.


  • Mod

    Könnte man dann nicht folgendes schreiben

    if( __builtin_expect( p != nullptr, 1 ) )
        delete p;
    


  • Arcoth schrieb:

    delete resultiert doch in einem API-Aufruf? Oder steckt der Nullpointertest schon im operator delete drin?

    Könnte so oder anders sein, es wäre nicht beobachtbar. In der Annahme, daß die API 0 nicht haben will, sonbdern einen Fehler zurückgibt, könnte die Lib trotzdem entweder vorher abfragen oder blind dagegenrennen und nachträglich den Fehler CALLED_API_FREE_WITH_NULLPTR wegverschweigen.
    Naja, ich tendiere mal ernsthaft dazu, daß man vorher fragt, spätestens seit unique_ptr. Und daß der Test im delete dem Compiler zu Optimierungszwecken bekanntgemacht wird (zur Not inline-wrapper mit nur dem if drum).


Anmelden zum Antworten