Ich verstehe nicht, warum das Hinzufügen einer Forward-Deklaration für eine Klasse die Größe ihres Zeigers auf den Member-Typ ändert
%Vor% Ausgabe VS2013:
4
Aber wenn ich die ersten zwei Zeilen in main () auskommentiere, dann ist die Ausgabe anders:
16
16
Nur ein einfaches Hinzufügen einer Vorwärtsdeklaration vor einer Definition von struct CL erhöht also die Größe eines Zeigers auf CL. Warum? Ich weiß, dass eine Größe des Elementfunktionszeigers von der Struktur eines Typs abhängt (z. B. können virtuelle Funktionen und Basisklassen diese erhöhen), aber warum kann der Operator sizeof auf einen Zeiger auf ein Element eines unvollständigen Typs angewendet werden? Oder kann es nicht? Ich habe es im Standard nicht gefunden
Der MSVC-Compiler verwendet verschiedene Größen für Zeiger auf Elementfunktionen als Optimierung. Diese Optimierung verstößt gegen den Standard. Kudos zu Igor Tandetnik Erwähnung von reinterpret_cast
in ein MSDN-Formular post , [expr.reinterpret.cast] p10
Ein Prvalue vom Typ "pointer to member of
X
vom TypT1
" kann sein explizit in einen prvalue eines anderen Typs "Zeiger auf Mitglied vonY
vom TypT2
"wennT1
undT2
beide Funktionstypen sind oder beide Objekttypen. Der Nullelementzeigerwert wird in konvertiert der Nullelementzeigerwert des Zieltyps Das Ergebnis von Diese Konvertierung ist nicht spezifiziert, außer in den folgenden Fällen:
- Konvertieren eines prvalue vom Typ "Zeiger auf Elementfunktion" in einen anderen Zeiger auf Elementfunktionstyp und zurück zu seinem Original type liefert den ursprünglichen Zeiger auf den Member-Wert.
Es gibt also eine Roundtrip-Garantie, die dazu führt, dass konforme Implementierungen die gleiche Größe für alle Zeiger auf Member-Funktionstypen verwenden.
Die MSVC-Optimierung wird durchgeführt, wenn /vmb
switch eingestellt ist. Für den Fall der Einzelvererbung benötigt der optimierte Zeiger auf die Elementfunktion nur einen void*
-Speicher, siehe Das Alte Neue Ding: Zeiger auf Mitgliedsfunktionen sind sehr seltsame Tiere .
Wenn Sie nur den Typ CL
weiterleiten und dann eine Pointer-zu-Member-Funktion bilden, wird die Optimierung hoffentlich deaktiviert (leider konnte ich dazu keine Dokumentation finden). Andernfalls erhalten Sie möglicherweise inkonsistente Größen vor und nach der Definition von CL
.
Übrigens können Sie in VS2010 inkonsistente Größen für Enumerationen erhalten, wenn Sie sie vorwärts emektieren ohne einen zugrunde liegenden Typ anzugeben und später explizit den zugrunde liegenden Typ für die Definition der Enumeration definieren. Dies funktioniert nur mit aktivierten Spracherweiterungen.
Tags und Links c++ incomplete-type pointer-to-member