158
Aby procesor mógł łatwiej przetworzyć dane kompilator może dodać do tej struktury jedno, ośmiobitowe pole. Wtedy struktura będzie wyglądała tak:
typedef struct {
unsigned char wiek; /*8 bitów */ unsigned char fill[l]; /* 8 bitów */ unsigned short dochod; /* 16 bitów */ unsigned char piec; /* 8 bitów */
} nasza,str;
Wtedy rozmiar zmiennych przechowujących wiek. płeć. oraz docltód będzie wynosił G4 bity będzie zatem potęgą liczby dwa i procesorowi dużo łatwiej będzie tak ułożoną strukturę przechowywać w pamięci cache. Jednak taka sytuacja nie zawsze jest pożądana. Aby jej za|x>biec w kompilatorze GNU CCC możemy użyć takiej oto linijki:
__attribute__ ((packed))
Dzięki użyciu tego atrybutu, kompilator zostanie “zmuszony” do braku ingerencji w naszą strukturę. Jesst jednak jeszcze jeden, być może bardziej elegancki sposób na obejście dopełniania. Zauważyłeś, że dopełnienie, dodane przez kompilator pojawiło się między pok-m o długości 8 bitów (piec) oraz polem o długości 32 bitów (dochod). Wyrównywanie pok*ga na tym. że dana zmienna |M>winna być umieszczona pod adresem będącym wielokrotnością jej rozmiaru. Oznacza to, że jeśli np. mamy w strukturze na początku dwie zmienne, o rozmiarze jednego bajta a potem jedną zmienną, o rozmiarze 4 bajtów, to pomiędzy polami o rozmiarze 2 bajtów, a polem czterobajtowym pojawi się dwubajtowe do|>ełnienie. Może Ci się wydawać, że jest to tylko nk*potrzebne mącenie w głowie, jednak niektóre architektury (zwłaszcza typu RISC') mogą nie wykonać kodu. który nie został wyrównany. Dlatego, naszą strukturę powinniśmy zapisać mniej więcej tak:
typedef struct {
unsigned short dochod; /• 16 bitów */ unsigned char wiek; /* 8 bitów */ unsigned char piec; /* 8 bitów */
> nasza,str;
W ten sposób wyrównana struktura nie będzie podlegała modyfikacjom przez kompilator oraz l>ę<lzie przenośna pomiędzy różnymi kompilatorami.
Wyrównywanie działa także na pojedynczych zmiennych w programie, jednak ten problem nie powoduje tyle zamieszania, co ingerencja kompilatora w układ pól struktury. Wyrównywanie zmiennych polega tylko na tym, że kompilator umieszcza je pod adresami, które są wiekikrotnością ich rozmiaru
Mając w domu dwa komputery, o odmiennych architekturach (np. i386 oraz Sparc) możemy potrzebować stworzyć program dla jednej maszyny, mając do dyspozycji tylko drugi komputer. NU- musimy wtedy latać <k> znajomego, posiadającego od|>owicdni sprzęt. Możemy skorzystać z tzw. kompilacji skrośnej (ang. cross-compile). Polega ona na tym, że program nie jest kompilowany pod procesor, na którym działa kompilator, lecz na inną, zdefiniowaną wcześniej maszynę. Efekt ł>ę<lzie taki sam, a skompilowany program możemy bez problemu uruchomić rui drugim komputerze.