2013-08-19 27 views
11

In C++ 03 Code, wie würde ich portabel einen unsigned char[sizeof(T)] Puffer implementieren, der die gleiche Größe und Ausrichtung wie die eines bestimmten Typs T hat?Wie würde ich den ausgerichteten Stapelspeicher in C++ 03 portabel implementieren?

Zum Beispiel:

template<class T> 
void test() 
{ 
    unsigned char buffer[sizeof(T)]; // <----- how do I ensure this is aligned? 
    if (some_condition()) 
    { 
     T *const obj = new(buffer) T(); 
     // ... 
     obj->~T(); 
    } 
    else { /* use 'buffer' for something else */ } 
} 

Ist dies überhaupt möglich, oder sind Sie Compiler-Erweiterungen, um dies zu implementieren zu verwenden gezwungen?

+0

Interessante Frage. +1 um sich daran zu erinnern, den Destruktor manuell zu treffen (obwohl ich etwas verwirrt bin, wie du es durch eine 'const' machst. Ich muss wirklich auf meine 'const'-Platzierungen auffrischen). – WhozCraig

+0

@WhozCraig: Danke. Beachten Sie, dass der Zeiger nicht const ist, der Zeiger selbst ist. :) – Mehrdad

+0

Ja, das habe ich gerade gesehen. = P – WhozCraig

Antwort

7

In seiner Spalte Guru Of The Week #28 verwendet Herb Sutter eine Union, aber sie ist weniger robust als Boosts Bemühungen.

Boost's aligned_storage löst die blutigen Details für Sie. Wenn Sie sich die Implementierung ansehen, werden Sie MSCVs __alignof oder GCCs __alignof__ sowie eine andere Vorlage sehen: type_with_alignment.

Aus meiner eigenen Code-Basis, ich einmal verwendet (von der GOTW Link oben abgeleitet):

#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706) 
# pragma warning(push) 
# pragma warning(disable: 4371) 
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706) 
     union AlignedStorage 
     { 
     char  storage[sizeof(T)]; 
     int16  dummy0; 
     int32  dummy1; 
     int64  dummy2; 
     float  dummy3; 
     double  dummy4; 
     long double dummy5; 
     void  (*dummy6)(); 
     struct  dummy7; 
     int   dummy7::*dummy8; 
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215) 
# pragma warning(push) 
# pragma warning(disable: 4121) 
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215) 
     int   (dummy7::*dummy9)(int); 
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215) 
# pragma warning(pop) 
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140050215) 

     }; // AlignedStorage 
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706) 
# pragma warning(pop) 
#endif // #if (defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 150020706) 

In diesen Tagen ich würde nur auf Boost-verlassen, da es wahrscheinlich viele mehr Eckfällen und Compiler Besonderheiten abdeckt

+0

Zwei Probleme: (1) Ich frage, wie das ** in erster Linie umgesetzt wird **. Gibt es einen portablen Weg, oder erfordert es Compiler-Erweiterungen? (2) Was gebe ich als zweiten Template-Parameter (die Ausrichtung)? – Mehrdad

+0

Nach Ihrem Edit # 1 - Sie sagen also, es erfordert Compiler-Erweiterungen? – Mehrdad

+0

Nach Ihrer Bearbeitung # 2 - ja, ich kann alle möglichen Typen kombinieren, um die maximale Ausrichtung zu erreichen, aber das überschneidet Daten in vielen Fällen und verschwendet Platz. Ich versuche die ** gleiche ** Ausrichtung wie der Typ zu bekommen; nicht mehr, nicht weniger. – Mehrdad

2

Der Grund dafür, dass Compiler-Erweiterungen wie __alignof und __attribute__((aligned(n)) existieren, ist, dass das Ermitteln und Durchsetzen von Alignment nicht portabel in C und C++ implementiert werden kann. I.e. Der Standard erfordert dazu keine Mittel.

+0

Ich bin mir nicht sicher, ob Sie versuchen, es zu sagen * nicht * portabel implementiert ist, oder wenn es * nicht * portabel implementiert werden kann. Welches meinst du? – Mehrdad

+0

c/C++ Standard nur die Freiheit für den Compiler lassen, muss alles noch mindestens auf char ausgerichtet werden. In C++ 11 Alignement ist Teil des Standards tatsächlich, Ausrichtung ist wahrscheinlich portable zu den meisten bestehenden Architekturen. – GameDeveloper

+0

@Mehrdad C++ - Standard erfordert keine Einrichtungen dafür, daher die Erweiterungen. –

Verwandte Themen