Der this-Zeiger im if
-
Ich glaube, das war nicht ernst gemeint.
-
Also die Sache ist so: Die Methoden müssen einfach davon ausgehen, dass der this-Zeiger gültig ist, sie können es nicht überprüfen und nicht auch nicht beweisen, schließlich kann auch ein Zeiger, dessen Wert sich von nullptr unterscheidet ungültig sein. Man kann aber natürlich für Debugfälle insofern helfen, als dass man alle Zeiger immer auf 0 initialisiert oder zurücksetzt nach delete, dann sieht man recht schnell, dass man hier ein Problem mit den Lebenszeiten hat.
-
Man kann aber natürlich für Debugfälle insofern helfen, als dass man alle Zeiger immer auf 0 initialisiert oder zurücksetzt nach delete, dann sieht man recht schnell, dass man hier ein Problem mit den Lebenszeiten hat.
Eben nicht - gelöscht Zeiger lassen und dann den Debugger einem sagen lassen was schief geht!
-
Ok d.h also
Frage 1:
if(this)... ist gleichbeduetend mit if(this != 0)...
if(!this)... ist gleichbeduetend mit if(!this != 0)...Hmm habs immer noch nicht
...Ich konkretisiere mal die Frage ich z.B. schon öfters mal code gefunden in wie z.B das hier:
struct adr { string name; string adresse; adr *next; ///.... void del() { if(!this) return; if(next) { .... } }Frage 2:
Ich verstehe es nicht ??
Was bezweckt es ? Und im welchen Fall wird if(!this) erfüllt so das es zum return kommt ?Grüße
-
! negiert die Aussage zu der es bindet.
!pointer => !(pointer != 0) => (pointer==0)
-
Naja, ich habe vielleicht zu bildlich gesprochen, als ich von "machen" sprach. Aber der Debug-Build auf meiner Plattform packt da zumindest immer so tolle Werte wie 0xFEFEFEFE rein oder auch 0xDEADBEEF und gänzlich andere Kombinationen.
-
das Verfahren, den this Zeiger zu prüfen, ist nicht sehr weit verbreitet. es ist aber korrektes C++. ich hatte so etwas auch mal gemacht bei einer Klasse, wo die Anwender gelegentlich Methoden mit einem Nullpointer aufgerufen haben. die Fehlermeldung ist dann immer bei mir hängen geblieben, weil meine Klasse angeblich abgestürzt ist. nach der Umstellung ist die Fehlermeldung bei den Aufrufern im Bugzilla gelandet
#include <iostream> using namespace std; class MyInt { public: MyInt () { m_Value = 0; } bool getValue(int & i) { if (this == 0) return false; else { i = m_Value; return true; } } private: int m_Value; }; int main () { MyInt myIntObj; MyInt * p1 = & myIntObj; MyInt * p2 = 0; int i; cout << p1->getValue(i) << endl; cout << p2->getValue(i) << endl; return 0; }
-
Falsche Reaktion. Wenn jemand eine Methode auf einem Nullzeiger aufruft, ist das offensichtlich sein Fehler, nicht deiner. So etwas zu "korrigieren" führt nur zu völlig kaputtem Code.
Edit: Ach so, du hast das nicht so genutzt wie im Codebeispiel, sondern nur als Schutz vor Bugreports? Ja, kann man machen. Trotzdem ein komisches Beispiel, was soll das?
-
dd++ schrieb:
das Verfahren, den this Zeiger zu prüfen, ist nicht sehr weit verbreitet. es ist aber korrektes C++.
Nein, wie kommst du darauf?
Edit: achso, wenn du nur prüfen meinst, dann ist es natürlich korrekt, kann aber in einem Programm ohne UB nie passieren.
-
cooky451 schrieb:
Falsche Reaktion. Wenn jemand eine Methode auf einem Nullzeiger aufruft, ist das offensichtlich sein Fehler, nicht deiner.
... das hatte ich damals auch versucht, dem Entwickler und dem Projektleiter begreiflich zu machen. in einer perfekten Welt kommt so etwas natürlich nicht vor ...
-
Athar schrieb:
dd++ schrieb:
das Verfahren, den this Zeiger zu prüfen, ist nicht sehr weit verbreitet. es ist aber korrektes C++.
Nein, wie kommst du darauf?
Edit: achso, wenn du nur prüfen meinst, dann ist es natürlich korrekt, kann aber in einem Programm ohne UB nie passieren.es gibt auch Klassen, die registrieren ihren this Zeiger im Konstruktor einer globalen Liste und tragen sich im Destruktor wieder aus. demzufolge kann man den this Zeiger auch auf Plausibilität prüfen und bei Fehler ein return false machen ... nur so als Beispiel ...
-
Was aber auch eine mehr als fragwürdige Praxis ist.

-
dd++ schrieb:
es gibt auch Klassen, die registrieren ihren this Zeiger im Konstruktor einer globalen Liste und tragen sich im Destruktor wieder aus. demzufolge kann man den this Zeiger auch auf Plausibilität prüfen und bei Fehler ein return false machen ... nur so als Beispiel ...
Lol. Gibt auch Klassen, die haben auch einfach nur ein
bool valid;das im Konstruktor auf true und im Destruktor auf false gesetzt wird. ... nur so als Beispiel ...
-
dd++ schrieb:
es gibt auch Klassen, die registrieren ihren this Zeiger im Konstruktor einer globalen Liste und tragen sich im Destruktor wieder aus.
Sicher, aber was hat das mit diesem Fall zu tun?
demzufolge kann man den this Zeiger auch auf Plausibilität prüfen und bei Fehler ein return false machen ... nur so als Beispiel ...
Das kann man zwar, aber bereits der Aufruf der Methode (bzw. das vorher stattfindende Dereferenzieren des null-Zeigers) ist UB, auch wenn sich das bei nicht-polymorphen Klassen in gängigen Implementationen tatsächlich so äußert, dass der this-Zeiger null ist und die Methode davon abgesehen normal aufgerufen wird.
-
es geht darum, daß bei mir gelegentlich Meldungen im Bugzilla gelandet sind, die daher kommen, daß jemand meine Methode mit einem Nullpointer aufgerufen hat. bei einer virtuellen Methode kommt er gar nicht erst in meine Methode hinein und es knallt beim Aufrufer. bei einer nichtvirtuellen Methode kann ich solange (wohldefiniert und nicht implementierungsabh.) in der Methode arbeiten, wie der this Zeiger nicht dereferenziert wird. und wenn ich dann entsprechend reagiere, landet der Bugzilla Eintrag mit dem coredump wieder beim Aufrufer
-
dd++ schrieb:
es geht darum, daß bei mir gelegentlich Meldungen im Bugzilla gelandet sind, die daher kommen, daß jemand meine Methode mit einem Nullpointer aufgerufen hat.
Wenn du solche User hast und sich niemand über die Performanceverluste stört, kann man da nichts machen (ausser auf eine DAU-Programmiersprache wie Java wechseln).
Das ändert aber nichts daran, dass das kein "korrektes C++" ist, sondern so etwas wie ein UB-Detektions-Hack, der zufällig funktioniert.
-
erklär das mal dem Projektleiter: "laut ISO/IEC 14882 dürfte das eigentlich gar nicht passieren"
-
zur Ergänzung hier noch die entsprechenden Stellen aus dem ISO/IEC 14882:
5.2.2 Function call
4 When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument. If the function is a non-static member function, the this parameter of the function (9.3.2) shall be initialized with a pointer to the object of the call, converted as if by an explicit type conversion (5.4).9.3.2 The this pointer [class.this]
1 In the body of a non-static (9.3) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called.
-
dd++ schrieb:
5.2.2 Function call
4 When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument. If the function is a non-static member function, the this parameter of the function (9.3.2) shall be initialized with a pointer to the object of the call, converted as if by an explicit type conversion (5.4).9.3.2 The this pointer [class.this]
1 In the body of a non-static (9.3) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called.Wo steht da, dass this==0 UB ist?
(Du bist auf der richtigen Spur, aber es fehlt noch der zwingende Beweis)
-
Na irgendwo steht bestimmt auch noch geschrieben, dass kein Objekt an der Objekttypsezifischen Adresse 0 zu finden sei. Das heißt, wenn this == 0, dann kann da kein Objekt sein für das die Methode aufgerufen wurde und this soll aber auf "das" Objekt zeigen laut 5.5.2.
Irgendwie so?