2014-02-23 15 views
7

PROBLEMWie berechnet man Strukturauffüllung in C++ 11 während der Kompilierzeit?

Ich habe eine std :: vector eine

die Unmenge Foo
struct Foo 
{ 
    int m_i; 
    char m_c; 
    char m_padding[3]; // want to replace this 
}; 

ich dieses Stück von zusammenhängend Foo alle schnell in binärer Form in einem Schuss fwrite kann.

Mein Problem ist, wenn ich dieses m_padding nicht explizit hineinlege, es berechne und es selbst lösche, wird valgrind über nicht initialisierte Schreibvorgänge klagen.

FRAGE

Ist es möglich, 11 eine Template-Klasse in C++ zu schreiben, die diese Polsterung für mich während der Kompilierung berechnen wird?

Wenn ja, könnte ich es einfach am Ende von allen meinen Foo's hinzufügen und sie automatisch initialisieren/löschen, ohne von Valgrind zu beanstanden.

Ich kann es manuell tun, indem ich sizeof (padding) = sizeof (Foo) - sum (sizeof (Teile)), aber es wäre nett, eine Art von Klasse für diese Berechnung zu erstellen, da alle Informationen beim Kompilieren verfügbar sind -Zeit.

Der Einfachheit halber wird angenommen, dass Foo triviales Layout hat (type_traits ist ein wichtiges, aber tangentielles Problem). Ignorieren Sie auch Probleme bei der Bestellung/plattformübergreifende Probleme.

Möglicher Ansatz

Dies gilt nicht meine ursprüngliche Frage direkt beantworten, aber hvd Vorschlag impliziert einen einfacheren Ansatz, der für einige einfache Testfälle zu funktionieren scheint, dass ich versucht:

template<typename T> 
struct BZero 
{ 
    BZero() { std::memset(this, 0, sizeof(T)); } 
}; 

struct Foo : public BZero<Foo> 
{ 
    int m_i; 
    char m_c; 
}; 
+5

Sie * könnte * einfach 'memset' verwenden, um die gesamte Struktur vor dem Füllen der anderen Felder zu löschen. Im Allgemeinen haben Ihre Strukturen möglicherweise auch eine Auffüllung zwischen den Elementen, was (oder sollte) Valgrind gleichermaßen beschweren sollte, und das Hinzufügen eines Auffüllelements am Ende würde dieses Problem nicht beheben. – hvd

+0

@hvd Ich mag Ihren Vorschlag - ich könnte eine Klassenvorlage erstellen, die als Parameter Foo und Memset in diesem Konstruktor verwendet. Auf diese Weise kann Foo normal initialisiert werden. Ich werde das ausprobieren und das OP updaten, wenn es ok ist. Danke. – kfmfe04

+0

Hinweis: Wenn Sie von einer Basisklasse ableiten, darf der Compiler die abgeleiteten Klassenelemente im Basisklassen-Padding speichern. –

Antwort

0

Nicht sicher, wenn ich gut verstanden habe, was ist damit:

+4

Dies funktioniert nicht: 'sizeof (T)' meldet die * gepolsterte * Größe. –

3

Nun, ich kann zwei Möglichkeiten sehen:

  1. eine union Ihrer Klasse verwenden und eine Reihe von char so groß wie die Klasse
  2. Verwenden Sie eine Templat-Klasse und Meta-Programmierung der Polsterungen alle
  3. , um herauszufinden,

Unnötig die ehemalige zu sagen scheint viel einfacher, also hier gehen Sie:

Verwandte Themen