2010-03-24 11 views
11

Czy wskaźniki w systemie 64-bitowym są nadal wyrównane w 4 bajtach (podobnie jak w systemie 32-bitowym)? Czy są one uwaga 8 bajt wyrównany?C 64-bitowe wyrównywanie wskaźnika

Na przykład, w systemie 64-bitowym, jak duża jest następująca struktura danych:

struct a { 
    void* ptr; 
    char myChar; 
} 

Czy wskaźnik o 8 bajt wyrównane, powodując 7 bajtów dopełnienie dla znaku (całkowita = 8 + 8 = 16)? Czy wskaźnik byłby 4 bajtowy wyrównany (4 bajty + 4 bajty) powodując 3 bajty dopełnienia (łącznie = 4 + 4 + 4 = 12)?

Dzięki Ryan

+7

Przez chwilę przeczytałem "C64". – Thilo

Odpowiedz

6

Wyrównanie danych i pakowanie są specyficzne dla implementacji i zazwyczaj można je zmienić z ustawień kompilatora (lub nawet z pragmami).

Jednak zakładając, że korzystasz z ustawień domyślnych, w większości (jeśli nie we wszystkich) kompilatorach struktura powinna wynieść łącznie 16 bajtów. Powodem jest to, że komputery odczytują porcję danych z rozmiarem jej natywnego rozmiaru słowa (co stanowi 8 bajtów w systemie 64-bitowym). Gdyby było to przesunięcie do 4-bajtowych przesunięć, następna struktura nie byłaby poprawnie wyściełana do 64-bitowej granicy. Na przykład w przypadku arr [2], drugi element tablicy zaczynałby się od przesunięcia 12 bajtów, który nie znajduje się na granicy natywnego bajtu maszyny.

6

I nie sądzę, że można polegać na wszelkich twardych i szybkich zasad. Myślę, że jest to funkcja kompilatora, którego używasz i opcje kompilacji, które wybierzesz.

Najlepiej jest napisać program, który przetestuje to i wypisze plik nagłówkowy, który kodyfikuje reguły wyrównania jako #define s. Możesz również po prostu obliczyć, co Cię interesuje bezpośrednio w makrach.

3

Zazwyczaj w systemie 64-bitowe:

struct a { 
    void* ptr;  // size is 8 bytes, alignment is 8 
    char myChar; // size is 1 byte, alignment is 1 
        // padding of 7 bytes so array elements will be properly aligned 
} 

do całkowitego rozmiaru 16 bajtów.

Ale to jest cała implementacja zdefiniowana - podaję tylko przykład, który prawdopodobnie będzie prawdziwy dla wielu (najbardziej?) 64-bitowych systemów.

0

Musisz zapoznać się z dokumentacją dla konkretnej ABI, którą jesteś zainteresowany. Na przykład tutaj jest the System V ABI x86-64 architeture supplement - na stronie 12 możesz zobaczyć, że wskaźniki na tej ABI są wyrównane do 8 bajtów (więc tak, struktura, którą masz show zostanie wyściełane do 16 bajtów).

1

Standardowy język nie zawiera żadnych oświadczeń dotyczących wypełnienia. Reguły wyrównania są specyficzne dla platformy (tzn. Musisz wyrównać inaczej na przykład na procesorze PowerPC niż na procesorze x86_64) i są one definiowane przez implementację, co oznacza, że ​​Twój kompilator może wykonywać dowolne działania (i może zmieniać to zachowanie przy użyciu różnych poleceń -line opcje lub po aktualizacji wersji).

Jestem przekonany, że każdyzalecenie wzdłuż linii „to zwykle to czy tamto” jest mylące i może być niebezpieczne.

  1. można napisać program testowy, który wykonuje kilka sizeof() i/lub offsetof() sprawozdania i pisze dla was nagłówek zawierający kilka #define s stwierdzające Podkładki używane.

  2. Możesz użyć , aby zrobić to za Ciebie.

  3. Należy przynajmniej dodać instrukcje assert(sizeof(...)) na początku swojej funkcji main(), aby otrzymywać informacje o błędnych założeniach.