Ich habe einige Inkonsistenzen zwischen Compilern mit diesem Programm entdeckt,
%Vor%Die meisten Compiler behaupten bei sizeof (C) == 8, dass die Größe von (C) eigentlich 12 ist. Der einzige Compiler, den ich nicht gefunden habe und der sagt, dass er 8 ist, ist Microsoft Visual Studio 2010.
Der Grund, der mir von jemandem gesagt wurde, der schlauer ist als ich, ist, dass es zwei separate Referenzen von A innerhalb von B gibt, die individuelle Offsets voneinander unterscheiden müssen. Erstens hat das von C abgeleitete A den Offset 0, und das zweite A innerhalb des Members b kann nicht den gleichen Offset wie das erste A bei 0 haben, so dass 4 Bytes Padding eingefügt werden.
Da die meisten Compiler dieses Verhalten implementiert haben, habe ich mich gefragt, in welchem Fall Sie sicherstellen müssen, dass beide A unterschiedliche Referenzen haben? Suchen Sie nach einer Intuition, warum dies der Fall ist?
Jemand sagte, dass es eine Bedingung sein könnte, die vom Standard gefordert wird, und wir waren neugierig auf was ist der Grund dafür?
Danke
Der Standard schreibt definitiv vor, dass die Adresse jedes Objekts desselben Typs unterschiedlich ist. Die relevante Klausel ist 5.10 [expr.eq] Absatz 1:
Zwei Zeiger des gleichen Typs sind gleich und genau dann, wenn sie beide null sind, zeigen beide auf die gleiche Funktion, oder beide repräsentieren die gleiche Adresse (3.9.2).
Dies wird benötigt, um die beiden Objekte zu unterscheiden. Objekte haben sowohl einen Wert als auch eine Identität. Für ein Basisklassen-Unterobjekt ist es sinnvoll, dieselbe Adresse wie die umschließende Klasse zu haben. Für ein Mitglied einer Klasse können Sie die Identität der zwei Objekte nach ihrem Typ unterscheiden, d. H. Es ist in Ordnung, dass sie die gleiche Adresse haben. Für zwei Objekte desselben Typs benötigen Sie immer noch etwas, um die Objekte nach ihrer Identität zu unterscheiden.
Ja, das wird in 10p8 erwähnt:
Ein Unterobjekt der Basisklasse darf keine Größe haben (Klausel 9); jedoch zwei Unterobjekte, die denselben Klassentyp haben und zu demselben gehören Das meiste abgeleitete Objekt darf nicht an der gleichen Adresse (5.10) zugeordnet sein.
In C
haben Sie zwei A
s, einer ist geerbt und der andere Teil von B
. Microsoft verwendet aggressiv und falsch die leere Basisklassenoptimierung, wenn dies nicht der Fall ist. Ich glaube, es ist bekannt, Bug, aber es ist wirklich schwer, den Fehlerbericht über Microsoft Connect zu finden.
In C ++ wird ein Objekt eindeutig durch ein Datenpaar bestimmt: seine Adresse und seinen Typ.
Wie Sie richtig bemerkt haben, enthalten sowohl C
als auch D
zwei verschiedene Unterobjekte A
, für die dies wahr sein muss. Je nachdem, wie Sie B
im Speicher anlegen, können Sie jedoch sehen, dass es nicht möglich ist, beide A
-subobjects an verschiedenen Adressen innerhalb einer 8-Byte-Struktur zu platzieren.
Warum drucken Sie nicht die tatsächlichen numerischen Adressen der Unterobjekte aus?
Tags und Links c++ diamond-problem sizeof