new & delete



  • Neku schrieb:

    Es ist irrelevant wo ein Zeiger hinzeigt, wenn er nicht benutzt wird. Der Aufruf macht somit keine Probleme.

    Laut Standard ist das Verhalten hier undefiniert. Es ist ja schön für dich, wenn du einen Compiler benutzt, der hier etwas definiertes tut, aber daraus solltest du (zumindest in diesem Unterforum) keine allgemeingültigen Ratschläge ableiten.



  • Neku schrieb:

    Es ist irrelevant wo ein Zeiger hinzeigt, wenn er nicht benutzt wird. Der Aufruf macht somit keine Probleme.

    ich bitte dich, wenn du einen nichtstandard compiler hast, der vielleicht auch möhren ordentlich umsetzt, hier keine falschen ratschläge zu geben!

    das verhalten hier ist undefiniert, und man sollte anfängern nie sagen, das es egal ist wo ein zeiger hinzeigt, solang er nicht benutzt wird!

    es ist nie egal wo ein zeiger hinzeigt!

    [Edit] zu spät



  • Laut Standard ist das was dort gemacht wird IMHO undefiniert, völlig egal was ein einzelner C++-Compiler da verwendet oder nicht verwendet.

    [Edit] Auch zu spät



  • int* p = (int*)2;
    

    Wieso sollte das ein Problem darstellen, wenn 'p' nicht genutzt wird?



  • p->tuWas();
    

    Hier wird p benutzt (_Egal_ was in tuWas passiert! Darum gehts im Übrigen auch bei Kapselung - nicht wissen zu müssen was tuWas tut.)



  • Neku schrieb:

    int* p = (int*)2;
    

    Wieso sollte das ein Problem darstellen, wenn 'p' nicht genutzt wird?

    es ging grad um den this zeiger?
    andere frage, wieso baust du die nen zeiger, lässt den irgendwo hinzeigen, wenn du den NIE benutzt?

    was willst du vermitteln?



  • Hat jemand einen Link zum C++ Standard? Hatte ich bisher noch nie benötigt, da ich weder bei VC++ noch bei g++ Probleme hatte bisher.



  • Neku schrieb:

    Hat jemand einen Link zum C++ Standard?

    Du kannst den C++ Standard für 30$ käuflich erwerben:
    http://webstore.ansi.org/ansidocstore/product.asp?sku=INCITS%2FISO%2FIEC+14882-2003

    Alternativ kannst du auch in den Final Draft schauen, den gibt es kostenlos:
    http://www.kuzbass.ru:8086/docs/isocpp/



  • Danke, habe bisher aber keine Informationen zu dem Problem gefunden.
    Dann schränke ich die Aussagen erstmal auf VC++ und g++ ein ^^



  • Ich kann noch mehr Verwirrung stiften:

    #include <iostream>
    using namespace std;
    
    class CTest 
     { 
     public: 
         CTest(){cout<<"constructor CTEST"<<endl;}; 
         ~CTest(){cout<<"Destructor CTEST "<<endl;}; 
         void SagHallo(){cout<<"CTest::Hallo()"<<endl;}; 
     };
     int main(int argc, char* argv[]) 
     { 
    
         CTest* pTest = 0; 
         pTest->SagHallo(); 
         return 1; 
     }
    

    geht auch 🙂
    Sollte man natürlich nicht tun, aber es gibt tatsächlich keinen Grund, warum es nicht gehen sollte. Allerdings geht das schon nicht, wenn die Methode virtuell ist. Aber so...

    Tommi



  • tntnet schrieb:

    [...] aber es gibt tatsächlich keinen Grund, warum es nicht gehen sollte.

    Doch siehe oben: Das Verhalten ist undefiniert. 👎



  • Man möge sich die folgenden Stellen im Standard anschauen:
    3.8. Object lifetime. Besonders 3.8/5
    9.3.1
    5.2.5/1-4

    Danach sollte einem klar sein, warum alle hier gezeigten Beispiele zu undefiniertem Verhalten führen.

    Mir ist allerdings nicht klar, warum man dazu erst in den Standard schauen muss. Es reicht eigentlich doch der gesunde Menschenverstand um verstehen zu können, dass hier Leichenfledderei betrieben wird. Und die ist in keiner Kultur gern gesehen.



  • Ich habe noch wie vor kein Problem damit nicht-statische Methoden aufzurufen, wenn der Objektzeiger nicht mehr gültig ist und 'this' nicht dereferenziert wird (oder eben geprüft).

    "if (!this)" benutze ich z.B. bisher und werde ich auch weiterhin.
    Die Idee dazu habe ich im übrigen von einem Spiel von Westwood 😛



  • Neku schrieb:

    Ich habe noch wie vor kein Problem damit nicht-statische Methoden aufzurufen, wenn der Objektzeiger nicht mehr gültig ist und 'this' nicht dereferenziert wird (oder eben geprüft).

    Eigentlich ist das nicht schwer zu verstehen. Aus Sicht des C++ Standards wird bei einem Methodenaufruf das was links von dem Punkt steht immer ausgewertet. Selbst wenn das was rechts vom Punkt steht eine *statische* Methode ist. Der C++ Standard garantiert dir deshalb nur ein gewisses Verhalten, wenn links ein gültiges Objekt steht. Ein ungültiges Objekt auf der linken Seite bedeutet: Kein gültiges C++ und damit Code aus einer Welt, die vom C++ Standard nicht spezifiziert wird.

    Aus diesem Grund kannst du keinerlei allgemeingültige Aussagen darüber treffen, was bei solch ungültigem Code passiert. Du kannst sagen: auf Compiler X in Version Y passiert Z. Du kannst deinen Code natürlich auch unter dieser Annahme schreiben. Du verlierst damit natürlich Portabilität. Denn Compiler Y könnte hier Nasenkobolde fliegen lassen und Compiler X könnte in Version Y.b sein Verhalten ändern.

    "if (!this)" benutze ich z.B. bisher und werde ich auch weiterhin.

    Die Abfrage ist aus Sicht von C++ natürlich ebenfalls blödsinn. Es gilt das oben gesagte.
    Ich würde mich hier fragen ob es keine elegantere Methode (also eine die nicht undefiniert ist) gibt, die das Problem löst. Falls es tatsächlich keine solche Methode gibt und ich sicher bin, dass fehlende Portabilität unwichtig ist: Hack kommentieren und Tests bauen, die eine Änderung im Verhalten des Compilers sofort sichtbar machen.

    Die Idee dazu habe ich im übrigen von einem Spiel von Westwood 😛

    Die werden hoffentlich einen Grund für solch einen grausamen Hack haben. Aber nur weil die einen haben, heißt das ja noch nicht, dass du einen hast.



  • Ich weiß nicht ob es jetzt schon gesagt wurde, aber ich glaube mal, der Compilier macht die Funktion statisch, da sie nicht auf elemente der Klasse zugreift. Wenn sie auf Elemente zugreift, sollte es abstürzen.

    mfg.


  • Mod

    jede nicht-statische memberfunktion bekommt implizit einen objektparameter - dieser ist funktionell äquivalent zu einer (cv-qualifizierten) referenz (ausser dass keine implizite konvertierung stattfindet mit ausnahme von rvalue-zu-lvalue konvertierung). abgesehen davon verhalten sich memberfunktionen nicht anders als normale namespace oder statische funktionen. der springende punkt ist, dass dieses lvalue-objekt bereits VOR eintritt in die funktion gebildet wird - es kommt nicht darauf an, ob dieser parameter tatsächlich innerhalb der funktion verwendet wird. nun ist das dereferenzieren eines NULL-zeigers aber unmittelbar undefiniertes verhalten (und selbst im nächsten standard gilt das zumindest für das bilden einer referenz auf diesen dereferenzierten zeiger).
    im übrigen wage ich zu behaupten, dass es niemals einen vorteil bringt einen test auf this!=0 in die memberfunktion zu verlagern (wenn wir mal davon ausgehen, dass das ok ist), der test ist in jedem falle einmal auszuführen, und innerhalb der funktion ist der kontext verloren. es widerspricht jedenfalls dem prinzip, fehler bzw. ungültige daten so frühzeitig wie möglich zu erkennen.



  • Frag mich was so ein Blödsinn soll ?
    Wofür gibt es einen Standard ?
    Genausogut kann ich einen Zeiger auf irgendeinen Speicherbereich zeigen lassen, von dem ich weiss, das Windows dort "immer" irgendwas ablegt.


Anmelden zum Antworten