2012-05-19 17 views
5

Próbowałem toJak wyrównać element struct w D?

struct Foo(T) 
{ 
    align(8) void[T.sizeof] data; 
} 

ale

static assert(Foo!(int).data.alignof == 8); 

nie powiedzie się, mówiąc mi wyrównanie jest nadal 1 zamiast 8.

Dlaczego tak jest i jak mogę to naprawić, aby działał na dowolne ustawienie, które ma moc 2 (nie tylko 8)?

Odpowiedz

5

Przeglądając źródło DMD, wygląda na to, że alignof nie uwzględnia atrybutów align.

Oto gdzie jest obsługiwane:

... if (ident == Id::__xalignof) 
{ 
    e = new IntegerExp(loc, alignsize(), Type::tsize_t); 
} 

ten konwertuje wyrażenie .alignof w size_t wyrażenia z wartością alignsize(), więc spójrzmy na alignsize() do statycznej tablicy:

unsigned TypeSArray::alignsize() 
{ 
    return next->alignsize(); 
} 

po prostu pobiera wyrównanie typu elementu (void) w twoim przypadku.

void jest obsługiwane przez TypeBasic::alignsize(), który tylko przekazuje do TypeBasic::size(0)

switch (ty) 
{ 
    ... 
    case Tvoid: 
     size = 1; 
     break; 
    ... 
} 

Patrząc jak inne rodzaje obsłużyć alignof, to nie wygląda align atrybuty są uwzględnione w ogóle, ale mogę się mylić . Może warto przetestować wyrównanie ręcznie.

+0

lol czekaj, co robi 'align'? Czy to tylko dekoracja? xD – Mehrdad

+0

Myślę, że 'align' działa, ale' alignof' po prostu dostaje wyrównanie typu, więc są oddzielnymi rzeczami. –

+0

Dziwne, natknąłem się na problemy, które doprowadziły mnie do sprawdzenia "alignof" ... muszę jednak sprawdzić dwukrotnie .. – Mehrdad