2011-07-22 12 views
7

Przepraszamy za głupie pytanie, ale jeśli muszę zapewnić wyrównanie struktury/klasy/związku, czy powinienem dodać atrybut ((wyrównany (wyrównanie))) do deklaracji typedef?Wyrównanie struktury w GCC (czy należy ustawić wyrównanie w typedef?)

class myAlignedStruct{} __attribute__ ((aligned(16))); 
typedef myAlignedStruct myAlignedStruct2; // Will myAlignedStruct2 be aligned by 16 bytes or not? 
+1

Zdecydowanie nie jest głupie pytanie. Myślę, że myAlignedStruct2 jest dopasowany w taki sam sposób jak myAlignedStruct, ale chciałby być tego pewien. Czy wypróbowałeś printf ("rozmiary:% d,% d", sizeof (myAlignedStruct), sizeof (myAlignedStruct2)); ? – Shlublu

+0

@Shlublu: 'sizeof' sprawdza pakowanie, ale wyrównanie jest inne! Nie ma standardowego operatora, ale GCC dostarcza '__alignof __()' jak pokazano w mojej odpowiedzi. –

+0

Ah, przepraszam, pomieszałem się! To sprawia, że ​​Twoje pytanie jest jeszcze bardziej interesujące! – Shlublu

Odpowiedz

8

Dodam atrybut ((wyrównane (align))) do typedef deklarację?

nr ... typedefs to tylko pseudonimy i aliasy dla określonego typu rzeczywistego, nie istnieje jako odrębny typ mieć inny wyrównanie, pakowania itp ..

#include <iostream> 

struct Default_Alignment 
{ 
    char c; 
}; 

struct Align16 
{ 
    char c; 
} __attribute__ ((aligned(16))); 

typedef Align16 Also_Align16; 

int main() 
{ 
    std::cout << __alignof__(Default_Alignment) << '\n'; 
    std::cout << __alignof__(Align16) << '\n'; 
    std::cout << __alignof__(Also_Align16) << '\n'; 
} 

wyjściowa:

1 
16 
16 
+0

Trochę zagubiony, Czy masz na myśli tak, myAlignedStruct2 być wyrównane o 16 bajtów? –

+0

@Als: Mam na myśli "czy powinienem dodać atrybut ((wyrównany (wyrównany))) do deklaracji typedef?": Nie. Tak, "myAlignedStruct2 [zostanie] wyrównane o 16 bajtów". Przykładowy kod i dane wyjściowe dodane powyżej .... –

+0

Moje +1. Zgadza się. Istnieją dwie wartości Q i wyraźna wzmianka o Tak i Nie dla każdego z nich jest teraz bardzo jasna. :) –

6

Przyjęta odpowiedź ("Nie") jest poprawna, ale chciałem wyjaśnić jedną potencjalnie wprowadzającą w błąd jej część. Dodałem komentarz, ale muszę sformatować jakiś kod; stąd nowa odpowiedź.

typedefs to tylko pseudonimy i aliasy dla określonego typu rzeczywistego, nie istnieje jako odrębny typ mieć inny wyrównanie, pakowania itp ..

ta jest błędna, przynajmniej dla GCC (kompilator OP) i GHS. Na przykład poniższe kompiluje się bezbłędnie, pokazując, że wyrównanie może być dołączone do typedef.

Perwersyjne wyrównanie (większe niż rozmiar obiektu) jest jedynie wartością szoku i rozrywki.

#define CASSERT(expr) { typedef char cassert_type[(expr) ? 1 : -1]; } 

typedef __attribute__((aligned(64))) uint8_t aligned_uint8_t; 

typedef struct 
{ 
    aligned_uint8_t t; 
} contains_aligned_char_t; 

void check_aligned_char_semantics() 
{ 
    CASSERT(__alignof(aligned_uint8_t) == 64); 
    CASSERT(sizeof(aligned_uint8_t) == 1); 
    CASSERT(sizeof(contains_aligned_char_t) == 64); 
}