class B
{
public:
virtual ~B(){};
// alternativ führt
// virtual void foo();
// ~B();
// zum gleichen Ergebnis
};
class A : public B
{
public:
virtual A& operator=(const A& toCopy)
{
return *this;
}
};
int main(void)
{
A* a = (A*)malloc(2*sizeof(A));
new(a+0) A;
new(a+1) A;
a[0].~A();
a[0] = a[1]; // crash
a[1].~A();
free(a);
}
Ich stehe gerade auf dem Schlauch, wieso MSVC2010 mir hier um die Ohren fliegt, sobald B mindestens eine virtuelle Funktion UND einen explizit deklarierten Destruktor UND zusätzlich A einen virtuellen Zuweisungsoperator für A& hat. Wenn der Zuweisungsoperator von A eine B& nimmt, gibts kein Problem (natürlich nur solange es nicht zusätzlich noch einen zweiten gibt, der eine A& nimmt, weil der sonst aufgerufen werden würde). Das Problem tritt auch nicht auf, wenn der Zuweisungsoperator von A nicht virtuell ist ().
Könnt ihr mir auf die Sprünge helfen, warum diese Kombi ein Problem ist?
Zuletzt geändert von kaiserludi am 07.02.2013, 22:52, insgesamt 1-mal geändert.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da :)
"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
a[0].~A(); // a[0] wird ZERSTÖRT
a[0] = a[1]; // Falsch: a[0] kein gültiges Objekt mehr, darf nicht länger wie gültiges Objekt modifiziert werden
kaiserludi hat geschrieben:Ich stehe gerade auf dem Schlauch, wieso MSVC2010 mir hier um die Ohren fliegt, sobald [...] A einen virtuellen Zuweisungsoperator für A& hat.
Weil dein a[0]-Objekt vor der Zuweisung zerstört wurde und somit insbesondere keinen passenden V-Table-Zeiger mehr hat.
Das heißt, dass die Zuweisung nach der Dekonstruktion durchgeht, wenn entweder der Zuweisungsoperator von A oder nichts von B virtuell ist oder B nur einen kompilererzeugten Destruktor hat, ist einfach Glück, aber wohldefiniertes Verhalten ist es dann eigentlich genauso wenig, korrekt?
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da :)
"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Genau, sobald dein Objekt zerstört wurde, ist solange keine Objektoperation darauf wohldefiniert, bis du an derselben Stelle wieder ein neues Objekt konstruiert hast.
So wird ein Schuh draus. Eigentlich auch klar. Dass in den meisten Fällen das undefinerte Verhalten einfach kein Problem verursacht hat, hat mich da wohl blind dafür gemacht, dass die Zuweisung ohne vorherige neue Konstruktion an der Stelle dennoch ein Bug ist. Danke.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da :)
"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Nunja; außer für POD. Dann beginnt mit der Zuweisung automatisch die neue Lebenszeit und alles ist wohldefiniert. Hat GCCs Aliasing-Analyse viele Kopfschmerzen bereitet.