Pentru unele platforme hardware, există cerințe stricte pentru alinierea datelor. La unele sisteme, de obicei RISC, încărcarea datelor incorect aliniate duce la generarea unei capcane, o eroare care poate fi rezolvată. Pe alte sisteme cu date aliniate în mod nenatural, puteți lucra, însă acest lucru duce la o scădere a producției.
voditelnosti. Când scrieți un cod portabil, trebuie să preveniți problemele legate de aliniere, iar datele de toate tipurile trebuie să aibă o aliniere naturală.
Cum să evitați problemele de aliniere
Compilatorul previne, de obicei, problemele legate de aliniere, prin alinierea naturală a tuturor tipurilor de date. De fapt, dezvoltatorii kernel-ului nu trebuie să se confrunte, de obicei, cu problemele asociate cu alinierea, acest lucru ar trebui să fie luat de dezvoltatorii compilatorului gcc. Cu toate acestea, astfel de probleme pot apărea în continuare atunci când dezvoltatorul trebuie să efectueze operațiuni cu indicatori și date de acces, fără a lua în considerare modul în care compilatorul efectuează operațiuni de acces la date.
char * p = câine [1];
nesemnate lung 1 = * (nesemnate lung *) p;
Dacă credeți că: „De ce ar trebui să fie nevoie“, atunci cel mai probabil dreptate, cu toate acestea, dacă am făcut acest lucru doar că, ceva de făcut și pe altcineva, așa că trebuie să fie exemple atent .. care se găsesc în viața reală, nu vor fi neapărat la fel de evidente.
Alinierea tipurilor de date non-standard
• Alinierea matricei este efectuată în același mod ca alinierea tipului de date al primului element (toate celelalte elemente vor fi aliniate corect automat).
• Alinierea sindicatului corespunde alinierii celui mai mare tip de date de la cele care sunt incluse în uniune.
• Alinierea structurii corespunde alinierii celui mai mare, dimensiunea, tip de date între tipurile de toate domeniile structurii.
În structuri, pot fi utilizate și alte modalități de umplere.
Structurile sunt umplute astfel încât fiecare dintre elementele sale să aibă o aliniere naturală. De exemplu, luați în considerare următoarea structură de date pe o mașină pe 32 de biți.
câine char; / * 1 octet * / cod negru nesemnat; / * 4 octeți * / shortpig nesemnat; / * 2 octeți * /
charfox; / * 1 octet * /
Această structură de date din memorie nu arată ca fiind datorată nevoii de aliniere naturală. În memorie, compilatorul creează o structură de date care arată ca cea care urmează.
câine char; / * 1 octet * / u8 __pad0 [3]; / * 3 octeți * / pisică nesemnată lungă; / * 4 octeți * / porc scurt nesemnat; / * 2 octeți * /
vrăjmaș; / * 1 octet * /
u8 padl; / * 1 octet * /
Variabilele de umplere sunt introduse pentru a asigura alinierea naturală a tuturor elementelor structurii. Prima variabilă de umplere introduce costuri suplimentare de memorie pentru a plasa câmpul ca la margine
Rețineți că expresia sizeo f (foo_struct) este egală cu 12 pentru orice instanță a acestei structuri pe cele mai multe platforme hardware pe 32 de biți. Compilatorul C adaugă automat elemente de umplere pentru a asigura alinierea necesară.
Adesea este posibilă rearanjarea câmpurilor de structură astfel încât să se evite necesitatea umplerii. Aceasta vă permite să obțineți date aliniate corect fără a introduce elemente suplimentare de umplere și, prin urmare, o structură mai mică.
structura structurii animalelor
pisică nesemnată lungă; / * 4 octeți * / porc scurt nesemnat; / * 2 octeți * / câine char; / * 1 octet * /
vrăjmaș; / * 1 octet * /
Această structură de date este de 8 octeți în mărime. Cu toate acestea, nu este întotdeauna posibilă rearanjarea elementelor structurale în locații și schimbarea definiției structurii.
tururi. De exemplu, dacă o structură este furnizată ca parte a unui standard sau este deja utilizată în codul existent, atunci ordinea câmpurilor nu poate fi modificată. Uneori, din anumite motive, este posibil să aveți nevoie de o ordine specială de câmpuri de structură, de exemplu o aliniere specială a variabilelor pentru a optimiza lovitura cache. Rețineți că, conform standardului ANSI C, compilatorul nu ar trebui să modifice ordinea câmpurilor în structurile de date5 - acest drept este deținut numai de programator.
Dezvoltatorii de kernel trebuie să țină seama de particularitățile de completare a schimbului de structuri de date: transmiterea structurilor prin rețea sau salvarea directă pe disc, deoarece umplerea necesară poate fi diferită pentru diferite platforme hardware. Acesta este unul dintre motivele pentru care limbajul de programare C nu are un operator de comparare a structurii. Memoria folosită pentru a popula structurile de date poate conține informații aleatorii, ceea ce face imposibilă compararea structurilor cu octeți. Dezvoltatorii limbajului de programare C au făcut corect că au lăsat problema comparării structurilor la discreția programatorului, care își poate crea propriile funcții de comparare în fiecare caz în parte pentru a utiliza caracteristicile de construcție a structurilor specifice.