man kann es aufrufen??



  • Wie, es geht im Visual Studio? Meinst du die Autovervollständigung? 😕 Ja, die analysiert eben nur die Struktur der Programmteile, nicht die momentane Aufrufbarkeit bezüglich eines aktuellen Programmzustandes.



  • nein der compiler übersetzt es doch in einen normale funktionsaufruf mit call und er tut den this ptr in den [ecx]. die funktion benutzt ja this nicht..aber macht ein compiler dies immer so?muss es IMMER funktionieren? wie kann ein compiler es denn sonst noch machen??


  • Administrator

    Es ist schlicht und einfach undefiniert. Hier eine Diskussion, welche erst kürzlich stattgefunden hat:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-240859.html

    Grüssli



  • Jede Klassenmethode erhält einen internen Parameter, welcher die Adresse der Instanz erhält.
    Zur Laufzeit(!) (nicht vom Compiler) kann nun geprüft werden, ob die Adresse der Klasseninstanz auf einen sinnvollen Datenbestand zeigt. Entsprechend kann eine Exception o.Ä. fliegen.



  • Dravere schrieb:

    Es ist schlicht und einfach undefiniert.

    wieso undefiniert? dereferenzieren von nullpointern ist ein astreiner fehler, oder ist das wieder so 'ne c++ -eigenart, dass es manchmal doch geht?
    🙂



  • Nativ umgesetzt ist jede Klassenmethode eine statische Prozedur. Die nicht-statischen Klassenmethoden (im Sinne von C++) erhalten eben einen Zeiger auf einen Datenbestand, welcher die veränderlichen Teile einer Klasseninstanz repräsentiert.

    Wird dieser Teil jedoch nicht benötigt, spricht ja nichts dagegen, die Klassenmethode aufzurufen, es handelt sich ja letztendlich eh nur um eine Sprungadresse, der einmalig in den Anwendungscode eingebettet ist.



  • marco.b schrieb:

    Nativ umgesetzt ist jede Klassenmethode eine statische Prozedur. Die nicht-statischen Klassenmethoden (im Sinne von C++) erhalten eben einen Zeiger auf einen Datenbestand, welcher die veränderlichen Teile einer Klasseninstanz repräsentiert.

    Die Frage war aber, ob das so auch im C++-Standard steht und damit überall so ist. Und das ist wohl eher nicht der Fall.



  • marco.b schrieb:

    Wird dieser Teil jedoch nicht benötigt, spricht ja nichts dagegen, die Klassenmethode aufzurufen, es handelt sich ja letztendlich eh nur um eine Sprungadresse, der einmalig in den Anwendungscode eingebettet ist.

    es ist aber keine statische methode. ausserdem macht er: ptr->hallo(); wobei ptr ein nullpointer ist. indirekte zugriffe über nullpointer sind bugs (jedenfalls in C, kann natürlich sein, dass C++ das anders sieht).
    🙂



  • +fricky schrieb:

    es ist aber keine statische methode. ausserdem macht er: ptr->hallo(); wobei ptr ein nullpointer ist. indirekte zugriffe über nullpointer sind bugs (jedenfalls in C, kann natürlich sein, dass C++ das anders sieht).
    🙂

    p->f();
    ist nichts anderes als
    f(p);

    natürlich ist das verhalten undefiniert und wenn der compiler zB die vtable sucht macht es auch BUMM. wenn er aber keine objekt spezifischen daten (wie zB vtable oder member) braucht wird es idR gut gehen.

    PS:
    vergleiche zB mit
    fread(0,0,0,0);
    das kann gut gehen (muss aber nicht).



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Rund um die Programmierung in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Shade Of Mine schrieb:

    p->f();
    ist nichts anderes als
    f(p);
    natürlich ist das verhalten undefiniert und wenn der compiler zB die vtable sucht macht es auch BUMM. wenn er aber keine objekt spezifischen daten (wie zB vtable oder member) braucht wird es idR gut gehen.

    mein fehler. ich hab's durch die C-brille gesehen. in C wäre p ein function pointer, der für einen erfolgreichen aufruf von f() natürlich nicht 0 sein darf.

    Shade Of Mine schrieb:

    vergleiche zB mit
    fread(0,0,0,0);
    das kann gut gehen (muss aber nicht).

    klar, aber nur, wenn fread das 'size' argument zuerst auswertet, als 0 erkennt und sofort rausspringt. aber sobald es einen der pointer dereferenziert, kracht es.
    🙂


  • Administrator

    +fricky schrieb:

    Dravere schrieb:

    Es ist schlicht und einfach undefiniert.

    wieso undefiniert? dereferenzieren von nullpointern ist ein astreiner fehler, oder ist das wieder so 'ne c++ -eigenart, dass es manchmal doch geht?
    🙂

    Soweit mir bekannt ist, ist es auch in C einfach als undefiniert beschrieben. Das wird schliesslich dazu benutzt, dass der Kompiler nicht auf solche Fehler prüfen muss, weder zur Kompile- noch zur Laufzeit. Dadurch kann der Kompiler deutlich besser optimieren und die Verantwortung wird in die Hände des Programmierer gelegt.

    Grüssli



  • +fricky schrieb:

    klar, aber nur, wenn fread das 'size' argument zuerst auswertet, als 0 erkennt und sofort rausspringt. aber sobald es einen der pointer dereferenziert, kracht es.
    🙂

    selbes in c++



  • +fricky schrieb:

    klar, aber nur, wenn fread das 'size' argument zuerst auswertet, als 0 erkennt und sofort rausspringt. aber sobald es einen der pointer dereferenziert, kracht es.
    🙂

    Unter Windows vielleicht. Woanders muss das nicht so sein.



  • +fricky schrieb:

    wieso undefiniert? dereferenzieren von nullpointern ist ein astreiner fehler, oder ist das wieder so 'ne c++ -eigenart, dass es manchmal doch geht?
    🙂

    Wie soll sich so ein astreiner Fehler im fertigen Programm äussern? Durch abruptes Beenden des Programms? Durch eine Fehlermeldung? Durch "Programm.exe funktioniert nicht mehr"?

    Beim Debuggen sollten Nullzeigerdereferenzierungen zu einer klaren Fehlermeldung führen. Im kompilierten Release-Pack dürften solche Fehler gar nicht vorkommen, aber ich würde mich nicht auf ein bestimmtes Verhalten verlassen, falls doch.



  • EDIT:
    Seite 2 übersehen 🙂
    Ist schon alles gesagt.



  • Dass offsetof Makro macht doch genau dass selbe... Es holt sich über einen Nullpointer der auf den Typ der struktur gecastet wird, die Addresse eines Elements...

    Und soweit ich weiß ist offsetof im Header

    <stddef.h>
    

    definiert...

    Wenn da ein Nullpointerzugriff funktioniert, warum sollte er beim Funktionsaufruf nicht funktionieren? 😕



  • Tobias Gerg schrieb:

    Dass offsetof Makro macht doch genau dass selbe...

    Nur es ist

    1. nicht im ANSI/ISO sondern "nur" POSIX Standard definiert
      und
    2. nicht definiert wie offsetof implementiert werden muss
      .

    Wenn zB bei p->f() f eine virtuelle Funktion ist, dann wuerde der Aufruf garantiert crashen da auf die vtable zugegriffen werden wuerde (die ein null pointer ja nicht hat).

    Weiters koennte der Aufruf ja auch etwaige invarianten ueberpruefen, was wieder zugriff auf objektspezifische Daten verlangen wuerde und wir haetten wieder einen absturz.

    deshalb ist es schon gut so, dass es undefiniert ist.
    wenn man weiss was man tut und die plattform kennt, kann man das fuer so sachen wie eben ein offsetof makro ausnutzen - aber prinzipiell ist es eben undefiniert.


  • Administrator

    Wie offsetof implementiert wird, ist nicht definiert. Wie es aussieht, ist er so in der MSVC Library umgesetzt, wobei allerdings dort schlussendlich kein Zugriff auf den Member erfolgt, sondern nur die Adresse geholt wird:

    #ifdef  _WIN64
    #define offsetof(s,m)   (size_t)( (ptrdiff_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) )
    #else
    #define offsetof(s,m)   (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
    #endif
    

    Es sieht also so aus, als wenn der MSVC dazu in der Lage ist, bzw. dadurch, dass nur die Adresse geholt wird, den Rest wohl wegoptimiert. Das heisst aber nicht, dass es dem Standard entsprechender und gültiger Code ist.
    In der nicht definierten Implementation nutzen die Kompiler oft ihre Eigenschaften aus, um etwas zu realisieren, verbessern oder vereinfachen.

    Die Implementation vom TDM GCC sieht übrigens so aus:

    #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
    

    Grüssli


Anmelden zum Antworten