man kann es aufrufen??
-
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.

-
+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
- nicht im ANSI/ISO sondern "nur" POSIX Standard definiert
und - 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.
- nicht im ANSI/ISO sondern "nur" POSIX Standard definiert
-
Wie
offsetofimplementiert 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)) #endifEs 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