Ich benutze C ++ für eingebettete Programmierung.
Angenommen, ich muss einen streng definierten (d. h. Byte für Byte) Klassentyp implementieren, kann ich einen Konstruktor und einige andere nicht-virtuelle Methoden hinzufügen, ohne dass sich Objekte dieses Typs auf Byte-Ebene ändern? Das heißt, kann ich davon ausgehen, dass keine zusätzlichen Daten hinzugefügt werden?
Ich nehme an, dass RTTI ausgeschaltet ist.
Ich möchte sicher sein, ob der C ++ Standard dies definiert.
Ja, wenn Sie nur Konstruktoren und / oder nicht-virtuelle Methoden hinzufügen, werden Sie die Größe oder das Layout der Klasse nicht ändern, da die ursprüngliche Klasse und die neue Klasse layoutkompatibel sind ( 9.2 Klassenmember [class.mem] # 17), aber nur, wenn es sich um Standardlayout-Klassen handelt .
Die Standard-Layout-Klassen sind definiert als:
9 Klassen [Klasse]
Eine Standardlayoutklasse ist eine Klasse, die:
- hat keine nicht statischen Datenelemente des Typs Nicht-Standardlayoutklasse (oder Array solcher Arten) oder Referenz,
- hat keine virtuellen Funktionen (10.3) und keine virtuellen Basisklassen (10.1),
- hat die gleiche Zugriffskontrolle (Klausel 11) für alle nicht statischen Daten Mitglieder,
- hat keine Nicht-Standard-Layout-Basisklassen,
- hat entweder keine nicht statischen Datenelemente in der abgeleiteten Klasse und höchstens eine Basisklasse mit nicht statischen Datenelementen oder keine Basis Klassen mit nicht statischen Datenelementen und
- hat keine Basisklassen des gleichen Typs wie die ersten nicht statischen Daten Mitglied.
Nein, nicht wirklich.
C ++ 11 sagt folgendes über sizeof
:
[C++11: 5.3.5/2]:
[..] Wenn auf eine Referenz oder einen Referenztyp angewendet, ist das Ergebnis die Größe des referenzierten Typs. Bei der Anwendung auf eine Klasse ist das Ergebnis die Anzahl der Bytes in einem Objekt dieser Klasse, einschließlich der Auffüllung, die zum Platzieren von Objekten dieses Typs in einem Array erforderlich ist. Die Größe einer am weitesten abgeleiteten Klasse muss größer sein als Null (1,8). Das Ergebnis der Anwendung vonsizeof
auf ein Basisklassenunterobjekt ist die Größe des Basisklassentyps. Bei der Anwendung auf ein Array ist das Ergebnis die Gesamtzahl der Bytes im Array. Dies bedeutet, dass die Größe eines Arrays aus n -Elementen n mal der Größe eines Elements ist.
... und das ist es auch schon. Es gibt nicht an, was "erforderlich ist, um Objekte dieses Typs in einem Array zu platzieren", sondern stattdessen bis zum Ziel-ABI.
Der Itanium-ABI, der kürzlich aus seinem bisherigen Zuhause (grr) verschwunden ist, macht das die Art von Garantien, die Sie suchen, wenn ich mich richtig erinnere, aber das ist nicht das gleiche wie eine C ++ - Garantie. Nicht das Gleiche.
Sie können Compiler-spezifische Packing / Alignment-Optionen verwenden, um Datenelemente zu behandeln. Aber Raumgewinn aufgrund von virtuellen Funktionen liegt außerhalb Ihrer Kontrolle. Sie würden nicht erwarten, dass für nicht-virtuelle Funktionen Platz hinzugefügt wird, aber dies ist auch nicht "garantiert".
Sie können static_assert(sizeof T == x, "T needs to be x bytes wide")
erkennen, wenn Sie mit einer Codeänderung einige Annahmen gebrochen haben. Das ist das Beste, was du bekommst.
In C ++ 03 und vorher, nein. Es gibt keinerlei Garantien hinsichtlich des Layouts. In C ++ 11 gibt es die Idee von Layout-kompatibel, aber ich bin mir nicht sicher, wie weit es geht; Ich würde hoffen , dass das Hinzufügen einer nicht virtuellen Funktion zur Klasse die Layoutkompatibilität nicht beeinträchtigen würde. Auf der anderen Seite erwähnen Sie Embedded-Programmierung und Ausschalten von RTTI; Sie zählen wahrscheinlich auf viele andere Dinge, die von Ihrem Compiler garantiert werden, und nicht den Standard. (Die Möglichkeit, RTTI zum Beispiel auszuschalten.) Angesichts dessen würde ich empfehlen, nach einer Garantie durch den Compiler zu suchen. Ich vermute, dass die meisten Compiler, die auf eingebettete Systeme abzielen, detaillierte Beschreibungen des von ihnen generierten Layouts enthalten, und Sie können von dort aus fortfahren.
Sie können diese Garantie vom Working Draft C ++, n3242, 2011-02-28
ableiten9.2 Klassenmitglieder
18 Zwei Standardlayout-Struct-Typen (Abschnitt 9) sind Layout-kompatibel, wenn sie die gleiche Anzahl von Nicht-Static haben Datenelemente und entsprechende nicht statische Datenelemente (in der Reihenfolge der Deklarationen) sind Layout-kompatibel Typen (3.9).
Dies spricht nur von Datenmitgliedern , also zwei Klassen
%Vor%sollte Layout-kompatibel sein.
Und für was ist eine Standardlayout-Klasse
9 Klassen
7 Eine Standard-Layout-Klasse ist eine Klasse, die:
- hat keine nicht statischen Datenelemente vom Typ Nicht-Standard-Layout-Klasse (oder Array von solchen Typen) oder Referenz,
- hat keine virtuellen Funktionen (10.3) und keine virtuellen Basisklassen (10.1),
- hat die gleiche Zugriffskontrolle (Klausel 11) für alle nicht statischen Datenmitglieder,
- hat keine Nicht-Standard-Layout-Basisklassen,
- hat entweder keine nicht statischen Datenelemente in der abgeleiteten Klasse und höchstens eine Basisklasse mit nicht statische Datenelemente oder keine Basisklassen mit nicht statischen Datenelementen und
- hat keine Basisklassen des gleichen Typs wie der erste nicht statische Datenmember.108
Tags und Links c++