2013-02-23 9 views
10

Rozważmy zmienną deklarację:Czy dostęp do bajtów zmiennej __m128 przez union jest legalny?

union { 
     struct { 
      float x, y, z, padding; 
     } components; 
     __m128 sse; 
    } _data; 

Mój pomysł jest przypisanie wartości poprzez x, y, z dziedzinach, wykonywania obliczeń SSE2 i odczytać wynik przez x, y, z. Mam jednak niewielkie wątpliwości, czy jest to legalne. Moje obawy są zgodne: MSDN mówi, że zmienne __m128 są automatycznie wyrównane do granicy 16-bajtowej i zastanawiam się, czy mój związek może złamać to zachowanie. Czy są tu jeszcze jakieś inne problemy?

+0

Nie, wyrównanie nie stanowi problemu. Związek będzie miał wszystko, czego potrzeba, aby wszyscy jego członkowie działali poprawnie. –

+2

Należy również zauważyć, że przynajmniej w Visual Studio można uzyskać komponenty '__m128 sse;' z 'sse.m128_f32 [0]', 'sse.m128_f32 [1]', 'sse.m128_f32 [2]', 'sse.m128_f32 [3]', więc nie ma takiej potrzeby. –

+0

@ R.MartinhoFernandes i for gcc? –

Odpowiedz

6

Ujednolicenie linii powinno być w porządku, ale w przypadku systemu Windows może być możliwy bezpośredni dostęp do 32-bitowych komponentów. Od xmmintrin.h (DirectXMath):

typedef union __declspec(intrin_type) _CRT_ALIGN(16) __m128 { 
    float    m128_f32[4]; 
    unsigned __int64 m128_u64[2]; 
    __int8    m128_i8[16]; 
    __int16    m128_i16[8]; 
    __int32    m128_i32[4]; 
    __int64    m128_i64[2]; 
    unsigned __int8  m128_u8[16]; 
    unsigned __int16 m128_u16[8]; 
    unsigned __int32 m128_u32[4]; 
} __m128; 

Jak widać, nie ma tam 4 pływaków. Jeśli chcesz być paranoikiem, możesz prawdopodobnie zdefiniować wszystkie te same specjalności wyrównania i takie, aby upewnić się, że nic nie pęknie. O ile jednak widzę, i biorąc pod uwagę, że wspomniałeś MSDN w swojej odpowiedzi, powinieneś być dobry. Zarówno związek, jak i bezpośredni dostęp do niego powinny działać, jeśli wiesz, że masz kompatybilne pliki SSE. Możesz także przeglądać nagłówki DirectXMath, aby poznać sposób, w jaki system Windows definiuje i sam się w nim kryje: definiuje kilka makr, w zależności od tego, które z nich są dostępne podczas kompilacji.

EDYCJA: Jak mówi R.MartinhoFernandes w komentarzach, bezpośredni dostęp do niego jest prawdopodobnie mniejszym bólem głowy niż przedefiniowaniem go w związku.

+1

Chciałem zachować moje fragmenty kodu cross-platfrom, stąd sztuczka związkowa. –

+0

@VioletGiraffe Następnie związek powinien być w porządku. GCC powinien szanować związek, a także nie robić nic zabawnego, ale nie jestem ekspertem GCC i jestem pewien, że jakiś prawnik Standardese przyjdzie i potępi nas zarówno do najgłębszych piekieł za używanie "związku". –