C/Więcej o kompilowaniu: Różnice pomiędzy wersjami

m
m (lit.)
} nasza_str;
 
Wtedy rozmiar zmiennych przechowujących wiek, płeć, oraz dochód będzie wynosił 64 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. AbyMoże jejsię zapobiecokazać, że nasza struktura musi odzwierciedlać np. pojedynczy pakiet danych, przesyłanych przez sieć. Nie może być w niej zatem żadnych innych pól, poza tymi, które są istotne do transmisji. Aby wymusić na kompilatorze GNUwyrównanie 1-bajtowe (co w praktyce wyłącza je) należy GCCprzed możemydefinicją użyćstruktury takiejdodać otodwie linijki:
 
#pragma pack(push)
#pragma pack(1)
struct struktura { /*...*/ };
#pragma pack(pop)
 
W kompilatorze GCC mamy jeszcze jedną możliwość, po deklaracji struktury dodajemy przed średnikiem kończącym jedną linijkę:
 
__attribute__ ((packed))
 
Działa ona dokładnie tak samo, jak makra #pragma, jednak jest ona obecna tylko w kompilatorze GCC.
 
Dzięki użyciu tego atrybutu, kompilator zostanie "zmuszony" do braku ingerencji w naszą strukturę. Jest 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 polem o długości 8 bitów (plec) oraz polem o długości 32 bitów (dochod). Wyrównywanie polega na tym, że dana zmienna powinna 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 dopełnienie. Może Ci się wydawać, że jest to tylko niepotrzebne mącenie w głowie, jednak niektóre architektury (zwłaszcza typu [[w:RISC|RISC]]) mogą nie wykonać kodu, który nie został wyrównany. Dlatego, naszą strukturę powinniśmy zapisać mniej więcej tak:
1838

edycji