Verweise auf dieselben Basisklassen müssen separate Offsets im Speicher haben

8

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

    
coderdave 05.12.2012, 23:16
quelle

3 Antworten

3

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.

    
Dietmar Kühl 05.12.2012, 23:31
quelle
3

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.

    
Jesse Good 05.12.2012 23:24
quelle
1

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?

    
Kerrek SB 05.12.2012 23:32
quelle

Tags und Links