Warum ist das Aufrufen der Funktion für nicht virtuelle Mitglieder bei gelöschten Zeigern ein undefiniertes Verhalten?

Wie der Titel sagt:

Warum ist das Aufrufen der Funktion für nicht virtuelle Mitglieder bei gelöschten Zeigern ein undefiniertes Verhalten?

Beachten Sie, dass die Frage nicht fragt, ob es sich um ein undefiniertes Verhalten handeltWarum es ist undefiniertes Verhalten.

Bedenke diefolgendes Programm:

#include<iostream>
class Myclass
{
    //int i
    public:
      void doSomething()
      {
          std::cout<<"Inside doSomething";
          //i = 10;
      }
};

int main()
{
    Myclass *ptr = new Myclass;
    delete ptr;

    ptr->doSomething();

    return 0;
}

In dem obigen Code dereferenziert der Compiler nichtthis beim Aufruf der Member-FunktiondoSomething(). Beachten Sie, dass die Funktion keine virtuelle Funktion ist und die Compiler den Member-Funktionsaufruf in einen normalen Funktionsaufruf umwandeln, indem sie dies als ersten Parameter an die Funktion übergeben (soweit ich weiß, ist dies eine definierte Implementierung). Dies ist möglich, da der Compiler genau bestimmen kann, welche Funktion zum Zeitpunkt der Kompilierung selbst aufgerufen werden soll. Der Aufruf der Member-Funktion über einen gelöschten Zeiger führt also praktisch zu keiner Dereferenzierung derthis. Dasthis wird nur dereferenziert, wenn auf ein Mitglied innerhalb des Funktionskörpers zugegriffen wird (d. h .: Code in obigem Beispiel wird kommentiert, der zugreift)i)
Wenn innerhalb der Funktion nicht auf ein Mitglied zugegriffen wird, gibt es keinen Grund, warum der obige Code tatsächlich undefiniertes Verhalten hervorrufen sollte.

Warum ist das Standardmandat, dass die nicht virtuelle Memberfunktion über einen gelöschten Zeiger aufgerufen wird, ein undefiniertes Verhalten, obwohl es tatsächlich verlässlich sagen kann, dass die Dereferenzierung derthis sollte die Aussage sein, die undefiniertes Verhalten verursachen soll? Ist es nur der Einfachheit halber für die Benutzer der Sprache so, dass der Standard ihn einfach verallgemeinert, oder beinhaltet dieses Mandat eine tiefere Semantik?

Mein Gefühl ist, dass möglicherweise, da die Implementierung definiert ist, wie Compiler die Member-Funktion aufrufen können, dies der Grund dafür ist, dass Standard den tatsächlichen Punkt, an dem UB auftritt, nicht erzwingen kann.

Kann das jemand bestätigen?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage