sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/process/coding-stylemodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Simplified)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/zh_CN/process/coding-stylemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hChinese (Traditional)}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/zh_TW/process/coding-stylemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/ja_JP/process/coding-stylemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/ko_KR/process/coding-stylemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget(/translations/sp_SP/process/coding-stylemodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageItalianuh1h hh _documenthsourceNlineNubhwarning)}(hIn caso di dubbi sulla correttezza del contenuto di questa traduzione, l'unico riferimento valido è la documentazione ufficiale in inglese. Per maggiori informazioni consultate le :ref:`avvertenze `.h]h paragraph)}(hIn caso di dubbi sulla correttezza del contenuto di questa traduzione, l'unico riferimento valido è la documentazione ufficiale in inglese. Per maggiori informazioni consultate le :ref:`avvertenze `.h](hIn caso di dubbi sulla correttezza del contenuto di questa traduzione, l’unico riferimento valido è la documentazione ufficiale in inglese. Per maggiori informazioni consultate le }(hhhhhNhNubh)}(h!:ref:`avvertenze `h]hinline)}(hhh]h avvertenze}(hhhhhNhNubah}(h]h ](xrefstdstd-refeh"]h$]h&]uh1hhhubah}(h]h ]h"]h$]h&]refdoc'translations/it_IT/process/coding-style refdomainhŒreftyperef refexplicitrefwarn reftarget it_disclaimeruh1hh3Documentation/translations/it_IT/disclaimer-ita.rsthKhhubh.}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhU/var/lib/git/docbuild/linux/Documentation/translations/it_IT/process/coding-style.rsthKubh field_body)}(h;:ref:`Documentation/process/coding-style.rst `h]h)}(hjh]h)}(hjh]h)}(hjh]h&Documentation/process/coding-style.rst}(hjhhhNhNubah}(h]h ](hstdstd-refeh"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftyperef refexplicitrefwarnhԌ codingstyleuh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhhubeh}(h]h ]h"]h$]h&]uh1hhjhKhhhhubh)}(hhh](h)}(h Translatorh]h Translator}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj<hjhKubj)}(h)Federico Vaga h]h)}(h(Federico Vaga h](hFederico Vaga <}(hjQhhhNhNubh reference)}(hfederico.vaga@vaga.pv.ith]hfederico.vaga@vaga.pv.it}(hj[hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:federico.vaga@vaga.pv.ituh1jYhjQubh>}(hjQhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjMubah}(h]h ]h"]h$]h&]uh1jhj<ubeh}(h]h ]h"]h$]h&]uh1hhjhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhjhKubhtarget)}(h.. _it_codingstyle:h]h}(h]h ]h"]h$]h&]refidit-codingstyleuh1jhKhhhhhjubhsection)}(hhh](htitle)}(h$Stile del codice per il kernel Linuxh]h$Stile del codice per il kernel Linux}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhK ubh)}(hXQuesto è un breve documento che descrive lo stile di codice preferito per il kernel Linux. Lo stile di codifica è molto personale e non voglio **forzare** nessuno ad accettare il mio, ma questo stile è quello che dev'essere usato per qualsiasi cosa che io sia in grado di mantenere, e l'ho preferito anche per molte altre cose. Per favore, almeno tenete in considerazione le osservazioni espresse qui.h](hQuesto è un breve documento che descrive lo stile di codice preferito per il kernel Linux. Lo stile di codifica è molto personale e non voglio }(hjhhhNhNubhstrong)}(h **forzare**h]hforzare}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh nessuno ad accettare il mio, ma questo stile è quello che dev’essere usato per qualsiasi cosa che io sia in grado di mantenere, e l’ho preferito anche per molte altre cose. Per favore, almeno tenete in considerazione le osservazioni espresse qui.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhK hjhhubh)}(hLa prima cosa che suggerisco è quella di stamparsi una copia degli standard di codifica GNU e di NON leggerla. Bruciatela, è un grande gesto simbolico.h]hLa prima cosa che suggerisco è quella di stamparsi una copia degli standard di codifica GNU e di NON leggerla. Bruciatela, è un grande gesto simbolico.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubh)}(hComunque, ecco i punti:h]hComunque, ecco i punti:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubj)}(hhh](j)}(h1) Indentazioneh]h1) Indentazione}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKubh)}(hLa tabulazione (tab) è di 8 caratteri e così anche le indentazioni. Ci sono alcuni movimenti di eretici che vorrebbero l'indentazione a 4 (o perfino 2!) caratteri di profondità, che è simile al tentativo di definire il valore del pi-greco a 3.h]hLa tabulazione (tab) è di 8 caratteri e così anche le indentazioni. Ci sono alcuni movimenti di eretici che vorrebbero l’indentazione a 4 (o perfino 2!) caratteri di profondità, che è simile al tentativo di definire il valore del pi-greco a 3.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubh)}(hXMotivazione: l'idea dell'indentazione è di definire chiaramente dove un blocco di controllo inizia e finisce. Specialmente quando siete rimasti a guardare lo schermo per 20 ore a file, troverete molto più facile capire i livelli di indentazione se questi sono larghi.h]hXMotivazione: l’idea dell’indentazione è di definire chiaramente dove un blocco di controllo inizia e finisce. Specialmente quando siete rimasti a guardare lo schermo per 20 ore a file, troverete molto più facile capire i livelli di indentazione se questi sono larghi.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubh)}(hX;Ora, alcuni rivendicano che un'indentazione da 8 caratteri sposta il codice troppo a destra e che quindi rende difficile la lettura su schermi a 80 caratteri. La risposta a questa affermazione è che se vi servono più di 3 livelli di indentazione, siete comunque fregati e dovreste correggere il vostro programma.h]hX=Ora, alcuni rivendicano che un’indentazione da 8 caratteri sposta il codice troppo a destra e che quindi rende difficile la lettura su schermi a 80 caratteri. La risposta a questa affermazione è che se vi servono più di 3 livelli di indentazione, siete comunque fregati e dovreste correggere il vostro programma.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK$hjhhubh)}(hIn breve, l'indentazione ad 8 caratteri rende più facile la lettura, e in aggiunta vi avvisa quando state annidando troppo le vostre funzioni. Tenete ben a mente questo avviso.h]hIn breve, l’indentazione ad 8 caratteri rende più facile la lettura, e in aggiunta vi avvisa quando state annidando troppo le vostre funzioni. Tenete ben a mente questo avviso.}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK*hjhhubh)}(hAl fine di facilitare l'indentazione del costrutto switch, si preferisce allineare sulla stessa colonna la parola chiave ``switch`` e i suoi subordinati ``case``. In questo modo si evita una doppia indentazione per i ``case``. Un esempio.:h](h{Al fine di facilitare l’indentazione del costrutto switch, si preferisce allineare sulla stessa colonna la parola chiave }(hj1hhhNhNubhliteral)}(h ``switch``h]hswitch}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj1ubh e i suoi subordinati }(hj1hhhNhNubj:)}(h``case``h]hcase}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj1ubh8. In questo modo si evita una doppia indentazione per i }(hj1hhhNhNubj:)}(h``case``h]hcase}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj1ubh. Un esempio.:}(hj1hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhK.hjhhubh literal_block)}(hswitch (suffix) { case 'G': case 'g': mem <<= 30; break; case 'M': case 'm': mem <<= 20; break; case 'K': case 'k': mem <<= 10; fallthrough; default: break; }h]hswitch (suffix) { case 'G': case 'g': mem <<= 30; break; case 'M': case 'm': mem <<= 20; break; case 'K': case 'k': mem <<= 10; fallthrough; default: break; }}hjysbah}(h]h ]h"]h$]h&] xml:spacepreserveforcelanguagechighlight_args}uh1jwhjhK3hjhhubh)}(h[A meno che non vogliate nascondere qualcosa, non mettete più istruzioni sulla stessa riga:h]h[A meno che non vogliate nascondere qualcosa, non mettete più istruzioni sulla stessa riga:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKFhjhhubjx)}(h1if (condition) do_this; do_something_everytime;h]h1if (condition) do_this; do_something_everytime;}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKIhjhhubh)}(h.Non usate le virgole per evitare le parentesi:h]h.Non usate le virgole per evitare le parentesi:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKNhjhhubjx)}(h+if (condition) do_this(), do_that();h]h+if (condition) do_this(), do_that();}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKPhjhhubh)}(hBInvece, usate sempre le parentesi per racchiudere più istruzioni.h]hBInvece, usate sempre le parentesi per racchiudere più istruzioni.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKUhjhhubjx)}(h9 if (condition) { do_this(); do_that(); }h]h9 if (condition) { do_this(); do_that(); }}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKWhjhhubh)}(hNon mettete nemmeno più assegnamenti sulla stessa riga. Lo stile del kernel è ultrasemplice. Evitate espressioni intricate.h]hNon mettete nemmeno più assegnamenti sulla stessa riga. Lo stile del kernel è ultrasemplice. Evitate espressioni intricate.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK^hjhhubh)}(hAl di fuori dei commenti, della documentazione ed escludendo i Kconfig, gli spazi non vengono mai usati per l'indentazione, e l'esempio qui sopra è volutamente errato.h]hAl di fuori dei commenti, della documentazione ed escludendo i Kconfig, gli spazi non vengono mai usati per l’indentazione, e l’esempio qui sopra è volutamente errato.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKbhjhhubh)}(hWProcuratevi un buon editor di testo e non lasciate spazi bianchi alla fine delle righe.h]hWProcuratevi un buon editor di testo e non lasciate spazi bianchi alla fine delle righe.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKfhjhhubeh}(h] indentazioneah ]h"]1) indentazioneah$]h&]uh1jhjhhhjhKubj)}(hhh](j)}(h#2) Spezzare righe lunghe e stringheh]h#2) Spezzare righe lunghe e stringhe}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKkubh)}(h_Lo stile del codice riguarda la leggibilità e la manutenibilità utilizzando strumenti comuni.h]h_Lo stile del codice riguarda la leggibilità e la manutenibilità utilizzando strumenti comuni.}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKmhjhhubh)}(h2Come limite di riga si preferiscono le 80 colonne.h]h2Come limite di riga si preferiscono le 80 colonne.}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKphjhhubh)}(hEspressioni più lunghe di 80 colonne dovrebbero essere spezzettate in pezzi più piccoli, a meno che eccedere le 80 colonne non aiuti ad aumentare la leggibilità senza nascondere informazioni.h]hEspressioni più lunghe di 80 colonne dovrebbero essere spezzettate in pezzi più piccoli, a meno che eccedere le 80 colonne non aiuti ad aumentare la leggibilità senza nascondere informazioni.}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKrhjhhubh)}(hI nuovi pezzi derivati sono sostanzialmente più corti degli originali e vengono posizionati più a destra. Uno stile molto comune è quello di allineare i nuovi pezzi alla parentesi aperta di una funzione.h]hI nuovi pezzi derivati sono sostanzialmente più corti degli originali e vengono posizionati più a destra. Uno stile molto comune è quello di allineare i nuovi pezzi alla parentesi aperta di una funzione.}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKvhjhhubh)}(hdLo stesso si applica, nei file d'intestazione, alle funzioni con una lista di argomenti molto lunga.h]hfLo stesso si applica, nei file d’intestazione, alle funzioni con una lista di argomenti molto lunga.}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKzhjhhubh)}(hTuttavia, non spezzettate mai le stringhe visibili agli utenti come i messaggi di printk, questo perché inibireste la possibilità d'utilizzare grep per cercarle.h]hTuttavia, non spezzettate mai le stringhe visibili agli utenti come i messaggi di printk, questo perché inibireste la possibilità d’utilizzare grep per cercarle.}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhK}hjhhubeh}(h] spezzare-righe-lunghe-e-stringheah ]h"]#2) spezzare righe lunghe e stringheah$]h&]uh1jhjhhhjhKkubj)}(hhh](j)}(h-3) Posizionamento di parentesi graffe e spazih]h-3) Posizionamento di parentesi graffe e spazi}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhKubh)}(hXUn altro problema che s'affronta sempre quando si parla di stile in C è il posizionamento delle parentesi graffe. Al contrario della dimensione dell'indentazione, non ci sono motivi tecnici sulla base dei quali scegliere una strategia di posizionamento o un'altra; ma il modo qui preferito, come mostratoci dai profeti Kernighan e Ritchie, è quello di posizionare la parentesi graffa di apertura per ultima sulla riga, e quella di chiusura per prima su una nuova riga, così:h]hXUn altro problema che s’affronta sempre quando si parla di stile in C è il posizionamento delle parentesi graffe. Al contrario della dimensione dell’indentazione, non ci sono motivi tecnici sulla base dei quali scegliere una strategia di posizionamento o un’altra; ma il modo qui preferito, come mostratoci dai profeti Kernighan e Ritchie, è quello di posizionare la parentesi graffa di apertura per ultima sulla riga, e quella di chiusura per prima su una nuova riga, così:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubjx)}(h"if (x is true) { we do y }h]h"if (x is true) { we do y }}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKhjhhubh)}(hlQuesto è valido per tutte le espressioni che non siano funzioni (if, switch, for, while, do). Per esempio:h]hlQuesto è valido per tutte le espressioni che non siano funzioni (if, switch, for, while, do). Per esempio:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubjx)}(hswitch (action) { case KOBJ_ADD: return "add"; case KOBJ_REMOVE: return "remove"; case KOBJ_CHANGE: return "change"; default: return NULL; }h]hswitch (action) { case KOBJ_ADD: return "add"; case KOBJ_REMOVE: return "remove"; case KOBJ_CHANGE: return "change"; default: return NULL; }}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKhjhhubh)}(hTuttavia, c'è il caso speciale, le funzioni: queste hanno la parentesi graffa di apertura all'inizio della riga successiva, quindi:h]hTuttavia, c’è il caso speciale, le funzioni: queste hanno la parentesi graffa di apertura all’inizio della riga successiva, quindi:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubjx)}(h0int function(int x) { body of function }h]h0int function(int x) { body of function }}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKhjhhubh)}(hXEretici da tutto il mondo affermano che questa incoerenza è ... insomma ... incoerente, ma tutte le persone ragionevoli sanno che (a) K&R hanno **ragione** e (b) K&R hanno ragione. A parte questo, le funzioni sono comunque speciali (non potete annidarle in C).h](hEretici da tutto il mondo affermano che questa incoerenza è ... insomma ... incoerente, ma tutte le persone ragionevoli sanno che (a) K&R hanno }(hjhhhNhNubj)}(h **ragione**h]hragione}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhj e (b) K&R hanno ragione. A parte questo, le funzioni sono comunque speciali (non potete annidarle in C).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjhhubh)}(hXNotate che la graffa di chiusura è da sola su una riga propria, ad **eccezione** di quei casi dove è seguita dalla continuazione della stessa espressione, in pratica ``while`` nell'espressione do-while, oppure ``else`` nell'espressione if-else, come questo:h](hDNotate che la graffa di chiusura è da sola su una riga propria, ad }(hj hhhNhNubj)}(h **eccezione**h]h eccezione}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhW di quei casi dove è seguita dalla continuazione della stessa espressione, in pratica }(hj hhhNhNubj:)}(h ``while``h]hwhile}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubh% nell’espressione do-while, oppure }(hj hhhNhNubj:)}(h``else``h]helse}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubh) nell’espressione if-else, come questo:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjhhubjx)}(h1do { body of do-loop } while (condition);h]h1do { body of do-loop } while (condition);}hjPsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKhjhhubh)}(heh]he}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubjx)}(hPif (x == y) { .. } else if (x > y) { ... } else { .... }h]hPif (x == y) { .. } else if (x > y) { ... } else { .... }}hjmsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKhjhhubh)}(hMotivazione: K&R.h]hMotivazione: K&R.}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubh)}(hX.Inoltre, notate che questo posizionamento delle graffe minimizza il numero di righe vuote senza perdere di leggibilità. In questo modo, dato che le righe sul vostro schermo non sono una risorsa illimitata (pensate ad uno terminale con 25 righe), avrete delle righe vuote da riempire con dei commenti.h]hX.Inoltre, notate che questo posizionamento delle graffe minimizza il numero di righe vuote senza perdere di leggibilità. In questo modo, dato che le righe sul vostro schermo non sono una risorsa illimitata (pensate ad uno terminale con 25 righe), avrete delle righe vuote da riempire con dei commenti.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubh)}(hLNon usate inutilmente le graffe dove una singola espressione è sufficiente.h]hLNon usate inutilmente le graffe dove una singola espressione è sufficiente.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubjx)}(h if (condition) action();h]h if (condition) action();}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKhjhhubh)}(hjah]he}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubjx)}(h9if (condition) do_this(); else do_that();h]h9if (condition) do_this(); else do_that();}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKhjhhubh)}(hQuesto non vale nel caso in cui solo un ramo dell'espressione if-else contiene una sola espressione; in quest'ultimo caso usate le graffe per entrambe i rami:h]hQuesto non vale nel caso in cui solo un ramo dell’espressione if-else contiene una sola espressione; in quest’ultimo caso usate le graffe per entrambe i rami:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubjx)}(hVif (condition) { do_this(); do_that(); } else { otherwise(); }h]hVif (condition) { do_this(); do_that(); } else { otherwise(); }}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKhjhhubh)}(hNInoltre, usate le graffe se un ciclo contiene più di una semplice istruzione:h]hNInoltre, usate le graffe se un ciclo contiene più di una semplice istruzione:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjhhubjx)}(hGwhile (condition) { if (test) do_something(); }h]hGwhile (condition) { if (test) do_something(); }}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhKhjhhubj)}(hhh](j)}(h 3.1) Spazih]h 3.1) Spazi}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj hhhjhKubh)}(hXLo stile del kernel Linux per quanto riguarda gli spazi, dipende (principalmente) dalle funzioni e dalle parole chiave. Usate una spazio dopo (quasi tutte) le parole chiave. L'eccezioni più evidenti sono sizeof, typeof, alignof, e __attribute__, il cui aspetto è molto simile a quello delle funzioni (e in Linux, solitamente, sono usate con le parentesi, anche se il linguaggio non lo richiede; come ``sizeof info`` dopo aver dichiarato ``struct fileinfo info``).h](hXLo stile del kernel Linux per quanto riguarda gli spazi, dipende (principalmente) dalle funzioni e dalle parole chiave. Usate una spazio dopo (quasi tutte) le parole chiave. L’eccezioni più evidenti sono sizeof, typeof, alignof, e __attribute__, il cui aspetto è molto simile a quello delle funzioni (e in Linux, solitamente, sono usate con le parentesi, anche se il linguaggio non lo richiede; come }(hjhhhNhNubj:)}(h``sizeof info``h]h sizeof info}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh dopo aver dichiarato }(hjhhhNhNubj:)}(h``struct fileinfo info``h]hstruct fileinfo info}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhj hhubh)}(h=Quindi utilizzate uno spazio dopo le seguenti parole chiave::h]h * / % | & ^ <= >= == != ? :h]h5= + - < > * / % | & ^ <= >= == != ? :}hjsbah}(h]h ]h"]h$]h&]jjuh1jwhjhM"hj hhubh)}(h/ma non mettete spazi dopo gli operatori unari::h]h.ma non mettete spazi dopo gli operatori unari:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM$hj hhubjx)}(hA& * + - ~ ! sizeof typeof alignof __attribute__ definedh]hA& * + - ~ ! sizeof typeof alignof __attribute__ defined}hjsbah}(h]h ]h"]h$]h&]jjuh1jwhjhM&hj hhubh)}(hLnessuno spazio dopo l'operatore unario suffisso di incremento o decremento::h]hMnessuno spazio dopo l’operatore unario suffisso di incremento o decremento:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM(hj hhubjx)}(h++ --h]h++ --}hj+sbah}(h]h ]h"]h$]h&]jjuh1jwhjhM*hj hhubh)}(hLnessuno spazio dopo l'operatore unario prefisso di incremento o decremento::h]hMnessuno spazio dopo l’operatore unario prefisso di incremento o decremento:}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM,hj hhubjx)}(h++ --h]h++ --}hjGsbah}(h]h ]h"]h$]h&]jjuh1jwhjhM.hj hhubh)}(hSe nessuno spazio attorno agli operatori dei membri di una struttura ``.`` e ``->``.h](hDe nessuno spazio attorno agli operatori dei membri di una struttura }(hjUhhhNhNubj:)}(h``.``h]h.}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjUubh e }(hjUhhhNhNubj:)}(h``->``h]h->}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjUubh.}(hjUhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM0hj hhubh)}(hXNon lasciate spazi bianchi alla fine delle righe. Alcuni editor con l'indentazione ``furba`` inseriranno gli spazi bianchi all'inizio di una nuova riga in modo appropriato, quindi potrete scrivere la riga di codice successiva immediatamente. Tuttavia, alcuni di questi stessi editor non rimuovono questi spazi bianchi quando non scrivete nulla sulla nuova riga, ad esempio perché volete lasciare una riga vuota. Il risultato è che finirete per avere delle righe che contengono spazi bianchi in coda.h](hVNon lasciate spazi bianchi alla fine delle righe. Alcuni editor con l’indentazione }(hjhhhNhNubj:)}(h ``furba``h]hfurba}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubhX inseriranno gli spazi bianchi all’inizio di una nuova riga in modo appropriato, quindi potrete scrivere la riga di codice successiva immediatamente. Tuttavia, alcuni di questi stessi editor non rimuovono questi spazi bianchi quando non scrivete nulla sulla nuova riga, ad esempio perché volete lasciare una riga vuota. Il risultato è che finirete per avere delle righe che contengono spazi bianchi in coda.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM3hj hhubh)}(hX Git vi avviserà delle modifiche che aggiungono questi spazi vuoti di fine riga, e può opzionalmente rimuoverli per conto vostro; tuttavia, se state applicando una serie di modifiche, questo potrebbe far fallire delle modifiche successive perché il contesto delle righe verrà cambiato.h]hX Git vi avviserà delle modifiche che aggiungono questi spazi vuoti di fine riga, e può opzionalmente rimuoverli per conto vostro; tuttavia, se state applicando una serie di modifiche, questo potrebbe far fallire delle modifiche successive perché il contesto delle righe verrà cambiato.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM;hj hhubeh}(h]spaziah ]h"] 3.1) spaziah$]h&]uh1jhjhhhjhKubeh}(h]*posizionamento-di-parentesi-graffe-e-spaziah ]h"]-3) posizionamento di parentesi graffe e spaziah$]h&]uh1jhjhhhjhKubj)}(hhh](j)}(h4) Assegnare nomih]h4) Assegnare nomi}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMAubh)}(hXUC è un linguaggio spartano, e così dovrebbero esserlo i vostri nomi. Al contrario dei programmatori Modula-2 o Pascal, i programmatori C non usano nomi graziosi come ThisVariableIsATemporaryCounter. Un programmatore C chiamerebbe questa variabile ``tmp``, che è molto più facile da scrivere e non è una delle più difficili da capire.h](hC è un linguaggio spartano, e così dovrebbero esserlo i vostri nomi. Al contrario dei programmatori Modula-2 o Pascal, i programmatori C non usano nomi graziosi come ThisVariableIsATemporaryCounter. Un programmatore C chiamerebbe questa variabile }(hjhhhNhNubj:)}(h``tmp``h]htmp}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubhS, che è molto più facile da scrivere e non è una delle più difficili da capire.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMChjhhubh)}(hTUTTAVIA, nonostante i nomi con notazione mista siano da condannare, i nomi descrittivi per variabili globali sono un dovere. Chiamare una funzione globale ``pippo`` è un insulto.h](hTUTTAVIA, nonostante i nomi con notazione mista siano da condannare, i nomi descrittivi per variabili globali sono un dovere. Chiamare una funzione globale }(hjhhhNhNubj:)}(h ``pippo``h]hpippo}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh è un insulto.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMIhjhhubh)}(hX Le variabili GLOBALI (da usare solo se vi servono **davvero**) devono avere dei nomi descrittivi, così come le funzioni globali. Se avete una funzione che conta gli utenti attivi, dovreste chiamarla ``count_active_users()`` o qualcosa di simile, **non** dovreste chiamarla ``cntusr()``.h](h2Le variabili GLOBALI (da usare solo se vi servono }(hjhhhNhNubj)}(h **davvero**h]hdavvero}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh) devono avere dei nomi descrittivi, così come le funzioni globali. Se avete una funzione che conta gli utenti attivi, dovreste chiamarla }(hjhhhNhNubj:)}(h``count_active_users()``h]hcount_active_users()}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh o qualcosa di simile, }(hjhhhNhNubj)}(h**non**h]hnon}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh dovreste chiamarla }(hjhhhNhNubj:)}(h ``cntusr()``h]hcntusr()}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMMhjhhubh)}(hCodificare il tipo di funzione nel suo nome (quella cosa chiamata notazione ungherese) è stupido - il compilatore conosce comunque il tipo e può verificarli, e inoltre confonde i programmatori.h]hCodificare il tipo di funzione nel suo nome (quella cosa chiamata notazione ungherese) è stupido - il compilatore conosce comunque il tipo e può verificarli, e inoltre confonde i programmatori.}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMRhjhhubh)}(hXlLe variabili LOCALI dovrebbero avere nomi corti, e significativi. Se avete un qualsiasi contatore di ciclo, probabilmente sarà chiamato ``i``. Chiamarlo ``loop_counter`` non è produttivo, non ci sono possibilità che ``i`` possa non essere capito. Analogamente, ``tmp`` può essere una qualsiasi variabile che viene usata per salvare temporaneamente un valore.h](hLe variabili LOCALI dovrebbero avere nomi corti, e significativi. Se avete un qualsiasi contatore di ciclo, probabilmente sarà chiamato }(hjzhhhNhNubj:)}(h``i``h]hi}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjzubh . Chiamarlo }(hjzhhhNhNubj:)}(h``loop_counter``h]h loop_counter}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjzubh1 non è produttivo, non ci sono possibilità che }(hjzhhhNhNubj:)}(h``i``h]hi}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjzubh) possa non essere capito. Analogamente, }(hjzhhhNhNubj:)}(h``tmp``h]htmp}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjzubh[ può essere una qualsiasi variabile che viene usata per salvare temporaneamente un valore.}(hjzhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMVhjhhubh)}(hSe avete paura di fare casino coi nomi delle vostre variabili locali, allora avete un altro problema che è chiamato sindrome dello squilibrio dell'ormone della crescita delle funzioni. Vedere il capitolo 6 (funzioni).h]hSe avete paura di fare casino coi nomi delle vostre variabili locali, allora avete un altro problema che è chiamato sindrome dello squilibrio dell’ormone della crescita delle funzioni. Vedere il capitolo 6 (funzioni).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM\hjhhubeh}(h]assegnare-nomiah ]h"]4) assegnare nomiah$]h&]uh1jhjhhhjhMAubj)}(hhh](j)}(h 5) Definizione di tipi (typedef)h]h 5) Definizione di tipi (typedef)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMaubh)}(hwPer favore non usate cose come ``vps_t``. Usare il typedef per strutture e puntatori è uno **sbaglio**. Quando vedete:h](hPer favore non usate cose come }(hjhhhNhNubj:)}(h ``vps_t``h]hvps_t}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh4. Usare il typedef per strutture e puntatori è uno }(hjhhhNhNubj)}(h **sbaglio**h]hsbaglio}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. Quando vedete:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMchjhhubjx)}(hvps_t a;h]hvps_t a;}hj)sbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMfhjhhubh)}(h2nei sorgenti, cosa significa? Se, invece, dicesse:h]h2nei sorgenti, cosa significa? Se, invece, dicesse:}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMjhjhhubjx)}(hstruct virtual_container *a;h]hstruct virtual_container *a;}hjFsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMmhjhhubh)}(h*potreste dire cos'è effettivamente ``a``.h](h&potreste dire cos’è effettivamente }(hjUhhhNhNubj:)}(h``a``h]ha}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjUubh.}(hjUhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMqhjhhubh)}(hjMolte persone pensano che la definizione dei tipi ``migliori la leggibilità``. Non molto. Sono utili per:h](h2Molte persone pensano che la definizione dei tipi }(hjuhhhNhNubj:)}(h``migliori la leggibilità``h]hmigliori la leggibilità}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjuubh. Non molto. Sono utili per:}(hjuhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMshjhhubh block_quote)}(hX(a) gli oggetti completamente opachi (dove typedef viene proprio usato allo scopo di **nascondere** cosa sia davvero l'oggetto). Esempio: ``pte_t`` eccetera sono oggetti opachi che potete usare solamente con le loro funzioni accessorie. .. note:: Gli oggetti opachi e le ``funzioni accessorie`` non sono, di per se, una bella cosa. Il motivo per cui abbiamo cose come pte_t eccetera è che davvero non c'è alcuna informazione portabile. (b) i tipi chiaramente interi, dove l'astrazione **aiuta** ad evitare confusione sul fatto che siano ``int`` oppure ``long``. u8/u16/u32 sono typedef perfettamente accettabili, anche se ricadono nella categoria (d) piuttosto che in questa. .. note:: Ancora - dev'esserci una **ragione** per farlo. Se qualcosa è ``unsigned long``, non c'è alcun bisogno di avere: typedef unsigned long myfalgs_t; ma se ci sono chiare circostanze in cui potrebbe essere ``unsigned int`` e in altre configurazioni ``unsigned long``, allora certamente typedef è una buona scelta. (c) quando di rado create letteralmente dei **nuovi** tipi su cui effettuare verifiche. (d) circostanze eccezionali, in cui si definiscono nuovi tipi identici a quelli definiti dallo standard C99. Nonostante ci voglia poco tempo per abituare occhi e cervello all'uso dei tipi standard come ``uint32_t``, alcune persone ne obiettano l'uso. Perciò, i tipi specifici di Linux ``u8/u16/u32/u64`` e i loro equivalenti con segno, identici ai tipi standard, sono permessi- tuttavia, non sono obbligatori per il nuovo codice. (e) i tipi sicuri nella spazio utente. In alcune strutture dati visibili dallo spazio utente non possiamo richiedere l'uso dei tipi C99 e nemmeno i vari ``u32`` descritti prima. Perciò, utilizziamo __u32 e tipi simili in tutte le strutture dati condivise con lo spazio utente. h]henumerated_list)}(hhh](h list_item)}(hXgli oggetti completamente opachi (dove typedef viene proprio usato allo scopo di **nascondere** cosa sia davvero l'oggetto). Esempio: ``pte_t`` eccetera sono oggetti opachi che potete usare solamente con le loro funzioni accessorie. .. note:: Gli oggetti opachi e le ``funzioni accessorie`` non sono, di per se, una bella cosa. Il motivo per cui abbiamo cose come pte_t eccetera è che davvero non c'è alcuna informazione portabile. h](h)}(h|gli oggetti completamente opachi (dove typedef viene proprio usato allo scopo di **nascondere** cosa sia davvero l'oggetto).h](hQgli oggetti completamente opachi (dove typedef viene proprio usato allo scopo di }(hjhhhNhNubj)}(h**nascondere**h]h nascondere}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh cosa sia davvero l’oggetto).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMvhjubh)}(hkEsempio: ``pte_t`` eccetera sono oggetti opachi che potete usare solamente con le loro funzioni accessorie.h](h Esempio: }(hjhhhNhNubj:)}(h ``pte_t``h]hpte_t}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubhY eccetera sono oggetti opachi che potete usare solamente con le loro funzioni accessorie.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMyhjubhnote)}(hGli oggetti opachi e le ``funzioni accessorie`` non sono, di per se, una bella cosa. Il motivo per cui abbiamo cose come pte_t eccetera è che davvero non c'è alcuna informazione portabile.h]h)}(hGli oggetti opachi e le ``funzioni accessorie`` non sono, di per se, una bella cosa. Il motivo per cui abbiamo cose come pte_t eccetera è che davvero non c'è alcuna informazione portabile.h](hGli oggetti opachi e le }(hjhhhNhNubj:)}(h``funzioni accessorie``h]hfunzioni accessorie}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh non sono, di per se, una bella cosa. Il motivo per cui abbiamo cose come pte_t eccetera è che davvero non c’è alcuna informazione portabile.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM}hjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hX>i tipi chiaramente interi, dove l'astrazione **aiuta** ad evitare confusione sul fatto che siano ``int`` oppure ``long``. u8/u16/u32 sono typedef perfettamente accettabili, anche se ricadono nella categoria (d) piuttosto che in questa. .. note:: Ancora - dev'esserci una **ragione** per farlo. Se qualcosa è ``unsigned long``, non c'è alcun bisogno di avere: typedef unsigned long myfalgs_t; ma se ci sono chiare circostanze in cui potrebbe essere ``unsigned int`` e in altre configurazioni ``unsigned long``, allora certamente typedef è una buona scelta. h](h)}(hyi tipi chiaramente interi, dove l'astrazione **aiuta** ad evitare confusione sul fatto che siano ``int`` oppure ``long``.h](h/i tipi chiaramente interi, dove l’astrazione }(hj hhhNhNubj)}(h **aiuta**h]haiuta}(hj$ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh+ ad evitare confusione sul fatto che siano }(hj hhhNhNubj:)}(h``int``h]hint}(hj6 hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubh oppure }(hj hhhNhNubj:)}(h``long``h]hlong}(hjH hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj ubh)}(hqu8/u16/u32 sono typedef perfettamente accettabili, anche se ricadono nella categoria (d) piuttosto che in questa.h]hqu8/u16/u32 sono typedef perfettamente accettabili, anche se ricadono nella categoria (d) piuttosto che in questa.}(hj` hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj ubj)}(hX> Ancora - dev'esserci una **ragione** per farlo. Se qualcosa è ``unsigned long``, non c'è alcun bisogno di avere: typedef unsigned long myfalgs_t; ma se ci sono chiare circostanze in cui potrebbe essere ``unsigned int`` e in altre configurazioni ``unsigned long``, allora certamente typedef è una buona scelta.h](j)}(hAncora - dev'esserci una **ragione** per farlo. Se qualcosa è ``unsigned long``, non c'è alcun bisogno di avere: typedef unsigned long myfalgs_t; h](h)}(hrAncora - dev'esserci una **ragione** per farlo. Se qualcosa è ``unsigned long``, non c'è alcun bisogno di avere:h](hAncora - dev’esserci una }(hjv hhhNhNubj)}(h **ragione**h]hragione}(hj~ hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjv ubh per farlo. Se qualcosa è }(hjv hhhNhNubj:)}(h``unsigned long``h]h unsigned long}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjv ubh$, non c’è alcun bisogno di avere:}(hjv hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjr ubj)}(h!typedef unsigned long myfalgs_t; h]h)}(h typedef unsigned long myfalgs_t;h]h typedef unsigned long myfalgs_t;}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj ubah}(h]h ]h"]h$]h&]uh1jhjhMhjr ubeh}(h]h ]h"]h$]h&]uh1jhjhMhjn ubh)}(hma se ci sono chiare circostanze in cui potrebbe essere ``unsigned int`` e in altre configurazioni ``unsigned long``, allora certamente typedef è una buona scelta.h](h8ma se ci sono chiare circostanze in cui potrebbe essere }(hj hhhNhNubj:)}(h``unsigned int``h]h unsigned int}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubh e in altre configurazioni }(hj hhhNhNubj:)}(h``unsigned long``h]h unsigned long}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubh0, allora certamente typedef è una buona scelta.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjn ubeh}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hTquando di rado create letteralmente dei **nuovi** tipi su cui effettuare verifiche. h]h)}(hSquando di rado create letteralmente dei **nuovi** tipi su cui effettuare verifiche.h](h(quando di rado create letteralmente dei }(hj hhhNhNubj)}(h **nuovi**h]hnuovi}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh" tipi su cui effettuare verifiche.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj ubah}(h]h ]h"]h$]h&]uh1jhjubj)}(hXcircostanze eccezionali, in cui si definiscono nuovi tipi identici a quelli definiti dallo standard C99. Nonostante ci voglia poco tempo per abituare occhi e cervello all'uso dei tipi standard come ``uint32_t``, alcune persone ne obiettano l'uso. Perciò, i tipi specifici di Linux ``u8/u16/u32/u64`` e i loro equivalenti con segno, identici ai tipi standard, sono permessi- tuttavia, non sono obbligatori per il nuovo codice. h](h)}(hhcircostanze eccezionali, in cui si definiscono nuovi tipi identici a quelli definiti dallo standard C99.h]hhcircostanze eccezionali, in cui si definiscono nuovi tipi identici a quelli definiti dallo standard C99.}(hj2 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj. ubh)}(hNonostante ci voglia poco tempo per abituare occhi e cervello all'uso dei tipi standard come ``uint32_t``, alcune persone ne obiettano l'uso.h](h_Nonostante ci voglia poco tempo per abituare occhi e cervello all’uso dei tipi standard come }(hj@ hhhNhNubj:)}(h ``uint32_t``h]huint32_t}(hjH hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj@ ubh&, alcune persone ne obiettano l’uso.}(hj@ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj. ubh)}(hPerciò, i tipi specifici di Linux ``u8/u16/u32/u64`` e i loro equivalenti con segno, identici ai tipi standard, sono permessi- tuttavia, non sono obbligatori per il nuovo codice.h](h#Perciò, i tipi specifici di Linux }(hj` hhhNhNubj:)}(h``u8/u16/u32/u64``h]hu8/u16/u32/u64}(hjh hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj` ubh~ e i loro equivalenti con segno, identici ai tipi standard, sono permessi- tuttavia, non sono obbligatori per il nuovo codice.}(hj` hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj. ubeh}(h]h ]h"]h$]h&]uh1jhjubj)}(hXi tipi sicuri nella spazio utente. In alcune strutture dati visibili dallo spazio utente non possiamo richiedere l'uso dei tipi C99 e nemmeno i vari ``u32`` descritti prima. Perciò, utilizziamo __u32 e tipi simili in tutte le strutture dati condivise con lo spazio utente. h](h)}(h"i tipi sicuri nella spazio utente.h]h"i tipi sicuri nella spazio utente.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj ubh)}(hIn alcune strutture dati visibili dallo spazio utente non possiamo richiedere l'uso dei tipi C99 e nemmeno i vari ``u32`` descritti prima. Perciò, utilizziamo __u32 e tipi simili in tutte le strutture dati condivise con lo spazio utente.h](htIn alcune strutture dati visibili dallo spazio utente non possiamo richiedere l’uso dei tipi C99 e nemmeno i vari }(hj hhhNhNubj:)}(h``u32``h]hu32}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubhu descritti prima. Perciò, utilizziamo __u32 e tipi simili in tutte le strutture dati condivise con lo spazio utente.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj ubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]enumtype loweralphaprefix(suffix)uh1jhjubah}(h]h ]h"]h$]h&]uh1jhjhMvhjhhubh)}(hMagari ci sono altri casi validi, ma la regola di base dovrebbe essere di non usare MAI MAI un typedef a meno che non rientri in una delle regole descritte qui.h]hMagari ci sono altri casi validi, ma la regola di base dovrebbe essere di non usare MAI MAI un typedef a meno che non rientri in una delle regole descritte qui.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hIn generale, un puntatore, o una struttura a cui si ha accesso diretto in modo ragionevole, non dovrebbero **mai** essere definite con un typedef.h](hkIn generale, un puntatore, o una struttura a cui si ha accesso diretto in modo ragionevole, non dovrebbero }(hj hhhNhNubj)}(h**mai**h]hmai}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh essere definite con un typedef.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubeh}(h]definizione-di-tipi-typedefah ]h"] 5) definizione di tipi (typedef)ah$]h&]uh1jhjhhhjhMaubj)}(hhh](j)}(h 6) Funzionih]h 6) Funzioni}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj hhhjhMubh)}(hLe funzioni dovrebbero essere brevi e carine, e fare una cosa sola. Dovrebbero occupare uno o due schermi di testo (come tutti sappiamo, la dimensione di uno schermo secondo ISO/ANSI è di 80x24), e fare una cosa sola e bene.h]hLe funzioni dovrebbero essere brevi e carine, e fare una cosa sola. Dovrebbero occupare uno o due schermi di testo (come tutti sappiamo, la dimensione di uno schermo secondo ISO/ANSI è di 80x24), e fare una cosa sola e bene.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj hhubh)}(hX|La massima lunghezza di una funziona è inversamente proporzionale alla sua complessità e al livello di indentazione di quella funzione. Quindi, se avete una funzione che è concettualmente semplice ma che è implementata come un lunga (ma semplice) sequenza di caso-istruzione, dove avete molte piccole cose per molti casi differenti, allora va bene avere funzioni più lunghe.h]hX|La massima lunghezza di una funziona è inversamente proporzionale alla sua complessità e al livello di indentazione di quella funzione. Quindi, se avete una funzione che è concettualmente semplice ma che è implementata come un lunga (ma semplice) sequenza di caso-istruzione, dove avete molte piccole cose per molti casi differenti, allora va bene avere funzioni più lunghe.}(hj% hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj hhubh)}(hXComunque, se avete una funzione complessa e sospettate che uno studente non particolarmente dotato del primo anno delle scuole superiori potrebbe non capire cosa faccia la funzione, allora dovreste attenervi strettamente ai limiti. Usate funzioni di supporto con nomi descrittivi (potete chiedere al compilatore di renderle inline se credete che sia necessario per le prestazioni, e probabilmente farà un lavoro migliore di quanto avreste potuto fare voi).h]hXComunque, se avete una funzione complessa e sospettate che uno studente non particolarmente dotato del primo anno delle scuole superiori potrebbe non capire cosa faccia la funzione, allora dovreste attenervi strettamente ai limiti. Usate funzioni di supporto con nomi descrittivi (potete chiedere al compilatore di renderle inline se credete che sia necessario per le prestazioni, e probabilmente farà un lavoro migliore di quanto avreste potuto fare voi).}(hj3 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj hhubh)}(hXUn'altra misura delle funzioni sono il numero di variabili locali. Non dovrebbero eccedere le 5-10, oppure state sbagliando qualcosa. Ripensate la funzione, e dividetela in pezzettini. Generalmente, un cervello umano può seguire facilmente circa 7 cose diverse, di più lo confonderebbe. Lo sai d'essere brillante, ma magari vorresti riuscire a capire cos'avevi fatto due settimane prima.h]hXUn’altra misura delle funzioni sono il numero di variabili locali. Non dovrebbero eccedere le 5-10, oppure state sbagliando qualcosa. Ripensate la funzione, e dividetela in pezzettini. Generalmente, un cervello umano può seguire facilmente circa 7 cose diverse, di più lo confonderebbe. Lo sai d’essere brillante, ma magari vorresti riuscire a capire cos’avevi fatto due settimane prima.}(hjA hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj hhubh)}(hNei file sorgenti, separate le funzioni con una riga vuota. Se la funzione è esportata, la macro **EXPORT** per questa funzione deve seguire immediatamente la riga della parentesi graffa di chiusura. Ad esempio:h](hcNei file sorgenti, separate le funzioni con una riga vuota. Se la funzione è esportata, la macro }(hjO hhhNhNubj)}(h **EXPORT**h]hEXPORT}(hjW hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjO ubhh per questa funzione deve seguire immediatamente la riga della parentesi graffa di chiusura. Ad esempio:}(hjO hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj hhubjx)}(hfint system_is_up(void) { return system_state == SYSTEM_RUNNING; } EXPORT_SYMBOL(system_is_up);h]hfint system_is_up(void) { return system_state == SYSTEM_RUNNING; } EXPORT_SYMBOL(system_is_up);}hjo sbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMhj hhubj)}(hhh](j)}(h6.1) Prototipi di funzioneh]h6.1) Prototipi di funzione}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj~ hhhjhMubh)}(hNei prototipi di funzione, includete i nomi dei parametri e i loro tipi. Nonostante questo non sia richiesto dal linguaggio C, in Linux viene preferito perché è un modo semplice per aggiungere informazioni importanti per il lettore.h]hNei prototipi di funzione, includete i nomi dei parametri e i loro tipi. Nonostante questo non sia richiesto dal linguaggio C, in Linux viene preferito perché è un modo semplice per aggiungere informazioni importanti per il lettore.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj~ hhubh)}(hNon usate la parola chiave ``extern`` con le dichiarazioni di funzione perché rende le righe più lunghe e non è strettamente necessario.h](hNon usate la parola chiave }(hj hhhNhNubj:)}(h ``extern``h]hextern}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubhf con le dichiarazioni di funzione perché rende le righe più lunghe e non è strettamente necessario.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj~ hhubh)}(hQuando scrivete i prototipi di funzione mantenete `l'ordine degli elementi `_.h](h2Quando scrivete i prototipi di funzione mantenete }(hj hhhNhNubjZ)}(h`l'ordine degli elementi `_h]hl’ordine degli elementi}(hj hhhNhNubah}(h]h ]h"]h$]h&]namel'ordine degli elementirefurifhttps://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/uh1jYhj ubj)}(hi h]h}(h]l-ordine-degli-elementiah ]h"]l'ordine degli elementiah$]h&]refurij uh1j referencedKhj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj~ hhubh)}(h9Prendiamo questa dichiarazione di funzione come esempio::h]h8Prendiamo questa dichiarazione di funzione come esempio:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj~ hhubjx)}(h__init void * __must_check action(enum magic value, size_t size, u8 count, char *fmt, ...) __printf(4, 5) __malloc;h]h__init void * __must_check action(enum magic value, size_t size, u8 count, char *fmt, ...) __printf(4, 5) __malloc;}hj sbah}(h]h ]h"]h$]h&]jjuh1jwhjhMhj~ hhubh)}(hOL'ordine suggerito per gli elementi di un prototipo di funzione è il seguente:h]hQL’ordine suggerito per gli elementi di un prototipo di funzione è il seguente:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj~ hhubh bullet_list)}(hhh](j)}(hclasse d'archiviazione (in questo caso ``static __always_inline``. Da notare che ``__always_inline`` è tecnicamente un attributo ma che viene trattato come ``inline``)h]h)}(hclasse d'archiviazione (in questo caso ``static __always_inline``. Da notare che ``__always_inline`` è tecnicamente un attributo ma che viene trattato come ``inline``)h](h)classe d’archiviazione (in questo caso }(hj" hhhNhNubj:)}(h``static __always_inline``h]hstatic __always_inline}(hj* hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj" ubh. Da notare che }(hj" hhhNhNubj:)}(h``__always_inline``h]h__always_inline}(hj< hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj" ubh9 è tecnicamente un attributo ma che viene trattato come }(hj" hhhNhNubj:)}(h ``inline``h]hinline}(hjN hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj" ubh)}(hj" hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj ubah}(h]h ]h"]h$]h&]uh1jhj hhhjhNubj)}(h~attributi della classe di archiviazione (in questo caso ``__init``, in altre parole la sezione, ma anche cose tipo ``__cold``)h]h)}(h~attributi della classe di archiviazione (in questo caso ``__init``, in altre parole la sezione, ma anche cose tipo ``__cold``)h](h8attributi della classe di archiviazione (in questo caso }(hjp hhhNhNubj:)}(h ``__init``h]h__init}(hjx hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjp ubh1, in altre parole la sezione, ma anche cose tipo }(hjp hhhNhNubj:)}(h ``__cold``h]h__cold}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjp ubh)}(hjp hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjl ubah}(h]h ]h"]h$]h&]uh1jhj hhhjhNubj)}(h/il tipo di ritorno (in questo caso, ``void *``)h]h)}(hj h](h$il tipo di ritorno (in questo caso, }(hj hhhNhNubj:)}(h ``void *``h]hvoid *}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubh)}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj ubah}(h]h ]h"]h$]h&]uh1jhj hhhjhNubj)}(hEattributi per il valore di ritorno (in questo caso, ``__must_check``)h]h)}(hj h](h4attributi per il valore di ritorno (in questo caso, }(hj hhhNhNubj:)}(h``__must_check``h]h __must_check}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubh)}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj ubah}(h]h ]h"]h$]h&]uh1jhj hhhjhNubj)}(h3il nome della funzione (in questo caso, ``action``)h]h)}(hj h](h(il nome della funzione (in questo caso, }(hj hhhNhNubj:)}(h ``action``h]haction}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj ubh)}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj ubah}(h]h ]h"]h$]h&]uh1jhj hhhjhNubj)}(hi parametri della funzione(in questo caso, ``(enum magic value, size_t size, u8 count, char *fmt, ...)``, da notare che va messo anche il nome del parametro)h]h)}(hi parametri della funzione(in questo caso, ``(enum magic value, size_t size, u8 count, char *fmt, ...)``, da notare che va messo anche il nome del parametro)h](h+i parametri della funzione(in questo caso, }(hj' hhhNhNubj:)}(h=``(enum magic value, size_t size, u8 count, char *fmt, ...)``h]h9(enum magic value, size_t size, u8 count, char *fmt, ...)}(hj/ hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj' ubh5, da notare che va messo anche il nome del parametro)}(hj' hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj# ubah}(h]h ]h"]h$]h&]uh1jhj hhhjhNubj)}(hbar); kfree(foo); return ret;h]hEerr: kfree(foo->bar); kfree(foo); return ret;}hj0sbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhM5hj hhubh)}(hIl baco in questo codice è che in alcuni punti d'uscita la variabile ``foo`` è NULL. Normalmente si corregge questo baco dividendo la gestione dell'errore in due parti ``err_free_bar:`` e ``err_free_foo:``:h](hHIl baco in questo codice è che in alcuni punti d’uscita la variabile }(hj?hhhNhNubj:)}(h``foo``h]hfoo}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj?ubh` è NULL. Normalmente si corregge questo baco dividendo la gestione dell’errore in due parti }(hj?hhhNhNubj:)}(h``err_free_bar:``h]h err_free_bar:}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj?ubh e }(hj?hhhNhNubj:)}(h``err_free_foo:``h]h err_free_foo:}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj?ubh:}(hj?hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM<hj hhubjx)}(h\err_free_bar: kfree(foo->bar); err_free_foo: kfree(foo); return ret;h]h\err_free_bar: kfree(foo->bar); err_free_foo: kfree(foo); return ret;}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhM@hj hhubh)}(h\Idealmente, dovreste simulare condizioni d'errore per verificare i vostri percorsi d'uscita.h]h`Idealmente, dovreste simulare condizioni d’errore per verificare i vostri percorsi d’uscita.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMHhj hhubeh}(h]'centralizzare-il-ritorno-delle-funzioniah ]h"]*7) centralizzare il ritorno delle funzioniah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h 8) Commentih]h 8) Commenti}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMMubh)}(hXI commenti sono una buona cosa, ma c'è anche il rischio di esagerare. MAI spiegare COME funziona il vostro codice in un commento: è molto meglio scrivere il codice di modo che il suo funzionamento sia ovvio, inoltre spiegare codice scritto male è una perdita di tempo.h]hXI commenti sono una buona cosa, ma c’è anche il rischio di esagerare. MAI spiegare COME funziona il vostro codice in un commento: è molto meglio scrivere il codice di modo che il suo funzionamento sia ovvio, inoltre spiegare codice scritto male è una perdita di tempo.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMOhjhhubh)}(hXSolitamente, i commenti devono dire COSA fa il codice, e non COME lo fa. Inoltre, cercate di evitare i commenti nel corpo della funzione: se la funzione è così complessa che dovete commentarla a pezzi, allora dovreste tornare al punto 6 per un momento. Potete mettere dei piccoli commenti per annotare o avvisare il lettore circa un qualcosa di particolarmente arguto (o brutto), ma cercate di non esagerare. Invece, mettete i commenti in testa alla funzione spiegando alle persone cosa fa, e possibilmente anche il PERCHÉ.h]hXSolitamente, i commenti devono dire COSA fa il codice, e non COME lo fa. Inoltre, cercate di evitare i commenti nel corpo della funzione: se la funzione è così complessa che dovete commentarla a pezzi, allora dovreste tornare al punto 6 per un momento. Potete mettere dei piccoli commenti per annotare o avvisare il lettore circa un qualcosa di particolarmente arguto (o brutto), ma cercate di non esagerare. Invece, mettete i commenti in testa alla funzione spiegando alle persone cosa fa, e possibilmente anche il PERCHÉ.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMThjhhubh)}(hPer favore, quando commentate una funzione dell'API del kernel usate il formato kernel-doc. Per maggiori dettagli, leggete i file in :ref::ref:`Documentation/translations/it_IT/doc-guide/ ` e in ``script/kernel-doc``.h](hPer favore, quando commentate una funzione dell’API del kernel usate il formato kernel-doc. Per maggiori dettagli, leggete i file in :ref:}(hjhhhNhNubh)}(hA:ref:`Documentation/translations/it_IT/doc-guide/ `h]h)}(hjh]h+Documentation/translations/it_IT/doc-guide/}(hjhhhNhNubah}(h]h ](hstdstd-refeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftyperef refexplicitrefwarnhԌ it_doc_guideuh1hhjhM]hjubh e in }(hjhhhNhNubj:)}(h``script/kernel-doc``h]hscript/kernel-doc}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM]hjhhubh)}(h>Lo stile preferito per i commenti più lunghi (multi-riga) è:h]h>Lo stile preferito per i commenti più lunghi (multi-riga) è:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMbhjhhubjx)}(h/* * This is the preferred style for multi-line * comments in the Linux kernel source code. * Please use it consistently. * * Description: A column of asterisks on the left side, * with beginning and ending almost-blank lines. */h]h/* * This is the preferred style for multi-line * comments in the Linux kernel source code. * Please use it consistently. * * Description: A column of asterisks on the left side, * with beginning and ending almost-blank lines. */}hj'sbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMdhjhhubh)}(hÈ anche importante commentare i dati, sia per i tipi base che per tipi derivati. A questo scopo, dichiarate un dato per riga (niente virgole per una dichiarazione multipla). Questo vi lascerà spazio per un piccolo commento per spiegarne l'uso.h]hÈ anche importante commentare i dati, sia per i tipi base che per tipi derivati. A questo scopo, dichiarate un dato per riga (niente virgole per una dichiarazione multipla). Questo vi lascerà spazio per un piccolo commento per spiegarne l’uso.}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMohjhhubeh}(h]commentiah ]h"] 8) commentiah$]h&]uh1jhjhhhjhMMubj)}(hhh](j)}(h9) Avete fatto un pasticcioh]h9) Avete fatto un pasticcio}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjLhhhjhMvubh)}(hXVa bene, li facciamo tutti. Probabilmente vi è stato detto dal vostro aiutante Unix di fiducia che ``GNU emacs`` formatta automaticamente il codice C per conto vostro, e avete notato che sì, in effetti lo fa, ma che i modi predefiniti non sono proprio allettanti (infatti, sono peggio che premere tasti a caso - un numero infinito di scimmie che scrivono in GNU emacs non faranno mai un buon programma).h](heVa bene, li facciamo tutti. Probabilmente vi è stato detto dal vostro aiutante Unix di fiducia che }(hj]hhhNhNubj:)}(h ``GNU emacs``h]h GNU emacs}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj]ubhX$ formatta automaticamente il codice C per conto vostro, e avete notato che sì, in effetti lo fa, ma che i modi predefiniti non sono proprio allettanti (infatti, sono peggio che premere tasti a caso - un numero infinito di scimmie che scrivono in GNU emacs non faranno mai un buon programma).}(hj]hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMxhjLhhubh)}(hQuindi, potete sbarazzarvi di GNU emacs, o riconfigurarlo con valori più sensati. Per fare quest'ultima cosa, potete appiccicare il codice che segue nel vostro file .emacs:h]hQuindi, potete sbarazzarvi di GNU emacs, o riconfigurarlo con valori più sensati. Per fare quest’ultima cosa, potete appiccicare il codice che segue nel vostro file .emacs:}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjLhhubjx)}(hX(defun c-lineup-arglist-tabs-only (ignored) "Line up argument lists by tabs, not spaces" (let* ((anchor (c-langelem-pos c-syntactic-element)) (column (c-langelem-2nd-pos c-syntactic-element)) (offset (- (1+ column) anchor)) (steps (floor offset c-basic-offset))) (* (max steps 1) c-basic-offset))) (dir-locals-set-class-variables 'linux-kernel '((c-mode . ( (c-basic-offset . 8) (c-label-minimum-indentation . 0) (c-offsets-alist . ( (arglist-close . c-lineup-arglist-tabs-only) (arglist-cont-nonempty . (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)) (arglist-intro . +) (brace-list-intro . +) (c . c-lineup-C-comments) (case-label . 0) (comment-intro . c-lineup-comment) (cpp-define-intro . +) (cpp-macro . -1000) (cpp-macro-cont . +) (defun-block-intro . +) (else-clause . 0) (func-decl-cont . +) (inclass . +) (inher-cont . c-lineup-multi-inher) (knr-argdecl-intro . 0) (label . -1000) (statement . 0) (statement-block-intro . +) (statement-case-intro . +) (statement-cont . +) (substatement . +) )) (indent-tabs-mode . t) (show-trailing-whitespace . t) )))) (dir-locals-set-directory-class (expand-file-name "~/src/linux-trees") 'linux-kernel)h]hX(defun c-lineup-arglist-tabs-only (ignored) "Line up argument lists by tabs, not spaces" (let* ((anchor (c-langelem-pos c-syntactic-element)) (column (c-langelem-2nd-pos c-syntactic-element)) (offset (- (1+ column) anchor)) (steps (floor offset c-basic-offset))) (* (max steps 1) c-basic-offset))) (dir-locals-set-class-variables 'linux-kernel '((c-mode . ( (c-basic-offset . 8) (c-label-minimum-indentation . 0) (c-offsets-alist . ( (arglist-close . c-lineup-arglist-tabs-only) (arglist-cont-nonempty . (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)) (arglist-intro . +) (brace-list-intro . +) (c . c-lineup-C-comments) (case-label . 0) (comment-intro . c-lineup-comment) (cpp-define-intro . +) (cpp-macro . -1000) (cpp-macro-cont . +) (defun-block-intro . +) (else-clause . 0) (func-decl-cont . +) (inclass . +) (inher-cont . c-lineup-multi-inher) (knr-argdecl-intro . 0) (label . -1000) (statement . 0) (statement-block-intro . +) (statement-case-intro . +) (statement-cont . +) (substatement . +) )) (indent-tabs-mode . t) (show-trailing-whitespace . t) )))) (dir-locals-set-directory-class (expand-file-name "~/src/linux-trees") 'linux-kernel)}hjsbah}(h]h ]h"]h$]h&]jjjjelispj}uh1jwhjhMhjLhhubh)}(h|Questo farà funzionare meglio emacs con lo stile del kernel per i file che si trovano nella cartella ``~/src/linux-trees``.h](hfQuesto farà funzionare meglio emacs con lo stile del kernel per i file che si trovano nella cartella }(hjhhhNhNubj:)}(h``~/src/linux-trees``h]h~/src/linux-trees}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjLhhubh)}(htMa anche se doveste fallire nell'ottenere una formattazione sensata in emacs non tutto è perduto: usate ``indent``.h](hkMa anche se doveste fallire nell’ottenere una formattazione sensata in emacs non tutto è perduto: usate }(hjhhhNhNubj:)}(h ``indent``h]hindent}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjLhhubh)}(hXOra, ancora, GNU indent ha la stessa configurazione decerebrata di GNU emacs, ed è per questo che dovete passargli alcune opzioni da riga di comando. Tuttavia, non è così terribile, perché perfino i creatori di GNU indent riconoscono l'autorità di K&R (le persone del progetto GNU non sono cattive, sono solo mal indirizzate sull'argomento), quindi date ad indent le opzioni ``-kr -i8`` (che significa ``K&R, 8 caratteri di indentazione``), o utilizzate ``scripts/Lindent`` che indenterà usando l'ultimo stile.h](hXOra, ancora, GNU indent ha la stessa configurazione decerebrata di GNU emacs, ed è per questo che dovete passargli alcune opzioni da riga di comando. Tuttavia, non è così terribile, perché perfino i creatori di GNU indent riconoscono l’autorità di K&R (le persone del progetto GNU non sono cattive, sono solo mal indirizzate sull’argomento), quindi date ad indent le opzioni }(hjhhhNhNubj:)}(h ``-kr -i8``h]h-kr -i8}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh (che significa }(hjhhhNhNubj:)}(h$``K&R, 8 caratteri di indentazione``h]h K&R, 8 caratteri di indentazione}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh), o utilizzate }(hjhhhNhNubj:)}(h``scripts/Lindent``h]hscripts/Lindent}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh( che indenterà usando l’ultimo stile.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjLhhubh)}(h``indent`` ha un sacco di opzioni, e specialmente quando si tratta di riformattare i commenti dovreste dare un'occhiata alle pagine man. Ma ricordatevi: ``indent`` non è un correttore per una cattiva programmazione.h](j:)}(h ``indent``h]hindent}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh ha un sacco di opzioni, e specialmente quando si tratta di riformattare i commenti dovreste dare un’occhiata alle pagine man. Ma ricordatevi: }(hjhhhNhNubj:)}(h ``indent``h]hindent}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh5 non è un correttore per una cattiva programmazione.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjLhhubh)}(hXDa notare che potete utilizzare anche ``clang-format`` per aiutarvi con queste regole, per riformattare rapidamente ad automaticamente alcune parti del vostro codice, e per revisionare interi file al fine di identificare errori di stile, refusi e possibilmente anche delle migliorie. È anche utile per ordinare gli ``#include``, per allineare variabili/macro, per ridistribuire il testo e altre cose simili. Per maggiori dettagli, consultate il file :ref:`Documentation/translations/it_IT/dev-tools/clang-format.rst `.h](h&Da notare che potete utilizzare anche }(hjMhhhNhNubj:)}(h``clang-format``h]h clang-format}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjMubhX per aiutarvi con queste regole, per riformattare rapidamente ad automaticamente alcune parti del vostro codice, e per revisionare interi file al fine di identificare errori di stile, refusi e possibilmente anche delle migliorie. È anche utile per ordinare gli }(hjMhhhNhNubj:)}(h ``#include``h]h#include}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjMubh{, per allineare variabili/macro, per ridistribuire il testo e altre cose simili. Per maggiori dettagli, consultate il file }(hjMhhhNhNubh)}(hS:ref:`Documentation/translations/it_IT/dev-tools/clang-format.rst `h]h)}(hj{h]h;Documentation/translations/it_IT/dev-tools/clang-format.rst}(hj}hhhNhNubah}(h]h ](hstdstd-refeh"]h$]h&]uh1hhjyubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftyperef refexplicitrefwarnhԌit_clangformatuh1hhjhMhjMubh.}(hjMhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjLhhubh)}(hSe utilizzate un programma compatibile con EditorConfig, allora alcune configurazioni basilari come l'indentazione e la fine delle righe verranno applicate automaticamente. Per maggiori informazioni consultate la pagina: https://editorconfig.org/h](hSe utilizzate un programma compatibile con EditorConfig, allora alcune configurazioni basilari come l’indentazione e la fine delle righe verranno applicate automaticamente. Per maggiori informazioni consultate la pagina: }(hjhhhNhNubjZ)}(hhttps://editorconfig.org/h]hhttps://editorconfig.org/}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jYhjubeh}(h]h ]h"]h$]h&]uh1hhjhMhjLhhubeh}(h]avete-fatto-un-pasticcioah ]h"]9) avete fatto un pasticcioah$]h&]uh1jhjhhhjhMvubj)}(hhh](j)}(h"10) File di configurazione Kconfigh]h"10) File di configurazione Kconfig}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubh)}(hPer tutti i file di configurazione Kconfig* che si possono trovare nei sorgenti, l'indentazione è un po' differente. Le linee dopo un ``config`` sono indentate con un tab, mentre il testo descrittivo è indentato di ulteriori due spazi. Esempio::h](hPer tutti i file di configurazione Kconfig* che si possono trovare nei sorgenti, l’indentazione è un po’ differente. Le linee dopo un }(hjhhhNhNubj:)}(h ``config``h]hconfig}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubhf sono indentate con un tab, mentre il testo descrittivo è indentato di ulteriori due spazi. Esempio:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubjx)}(hXBconfig AUDIT bool "Auditing support" depends on NET help Enable auditing infrastructure that can be used with another kernel subsystem, such as SELinux (which requires this for logging of avc messages output). Does not do system-call auditing without CONFIG_AUDITSYSCALL.h]hXBconfig AUDIT bool "Auditing support" depends on NET help Enable auditing infrastructure that can be used with another kernel subsystem, such as SELinux (which requires this for logging of avc messages output). Does not do system-call auditing without CONFIG_AUDITSYSCALL.}hjsbah}(h]h ]h"]h$]h&]jjuh1jwhjhMhjhhubh)}(hLe funzionalità davvero pericolose (per esempio il supporto alla scrittura per certi filesystem) dovrebbero essere dichiarate chiaramente come tali nella stringa di titolo::h]hLe funzionalità davvero pericolose (per esempio il supporto alla scrittura per certi filesystem) dovrebbero essere dichiarate chiaramente come tali nella stringa di titolo:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubjx)}(h`config ADFS_FS_RW bool "ADFS write support (DANGEROUS)" depends on ADFS_FS ...h]h`config ADFS_FS_RW bool "ADFS write support (DANGEROUS)" depends on ADFS_FS ...}hjsbah}(h]h ]h"]h$]h&]jjuh1jwhjhMhjhhubh)}(h|Per la documentazione completa sui file di configurazione, consultate il documento Documentation/kbuild/kconfig-language.rsth]h|Per la documentazione completa sui file di configurazione, consultate il documento Documentation/kbuild/kconfig-language.rst}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubeh}(h]file-di-configurazione-kconfigah ]h"]"10) file di configurazione kconfigah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h11) Strutture datih]h11) Strutture dati}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj9hhhjhMubh)}(hXLe strutture dati che hanno una visibilità superiore al contesto del singolo thread in cui vengono create e distrutte, dovrebbero sempre avere un contatore di riferimenti. Nel kernel non esiste un *garbage collector* (e fuori dal kernel i *garbage collector* sono lenti e inefficienti), questo significa che **dovete** assolutamente avere un contatore di riferimenti per ogni cosa che usate.h](hLe strutture dati che hanno una visibilità superiore al contesto del singolo thread in cui vengono create e distrutte, dovrebbero sempre avere un contatore di riferimenti. Nel kernel non esiste un }(hjJhhhNhNubhemphasis)}(h*garbage collector*h]hgarbage collector}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1jRhjJubh (e fuori dal kernel i }(hjJhhhNhNubjS)}(h*garbage collector*h]hgarbage collector}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1jRhjJubh2 sono lenti e inefficienti), questo significa che }(hjJhhhNhNubj)}(h **dovete**h]hdovete}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjJubhI assolutamente avere un contatore di riferimenti per ogni cosa che usate.}(hjJhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj9hhubh)}(hX>Avere un contatore di riferimenti significa che potete evitare la sincronizzazione e permette a più utenti di accedere alla struttura dati in parallelo - e non doversi preoccupare di una struttura dati che improvvisamente sparisce dalla loro vista perché il loro processo dormiva o stava facendo altro per un attimo.h]hX>Avere un contatore di riferimenti significa che potete evitare la sincronizzazione e permette a più utenti di accedere alla struttura dati in parallelo - e non doversi preoccupare di una struttura dati che improvvisamente sparisce dalla loro vista perché il loro processo dormiva o stava facendo altro per un attimo.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj9hhubh)}(hX6Da notare che la sincronizzazione **non** si sostituisce al conteggio dei riferimenti. La sincronizzazione ha lo scopo di mantenere le strutture dati coerenti, mentre il conteggio dei riferimenti è una tecnica di gestione della memoria. Solitamente servono entrambe le cose, e non vanno confuse fra di loro.h](h"Da notare che la sincronizzazione }(hjhhhNhNubj)}(h**non**h]hnon}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhX  si sostituisce al conteggio dei riferimenti. La sincronizzazione ha lo scopo di mantenere le strutture dati coerenti, mentre il conteggio dei riferimenti è una tecnica di gestione della memoria. Solitamente servono entrambe le cose, e non vanno confuse fra di loro.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj9hhubh)}(hX Quando si hanno diverse classi di utenti, le strutture dati possono avere due livelli di contatori di riferimenti. Il contatore di classe conta il numero dei suoi utenti, e il contatore globale viene decrementato una sola volta quando il contatore di classe va a zero.h]hX Quando si hanno diverse classi di utenti, le strutture dati possono avere due livelli di contatori di riferimenti. Il contatore di classe conta il numero dei suoi utenti, e il contatore globale viene decrementato una sola volta quando il contatore di classe va a zero.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj9hhubh)}(hUn esempio di questo tipo di conteggio dei riferimenti multi-livello può essere trovato nella gestore della memoria (``struct mm_sturct``: mm_user e mm_count), e nel codice dei filesystem (``struct super_block``: s_count e s_active).h](hvUn esempio di questo tipo di conteggio dei riferimenti multi-livello può essere trovato nella gestore della memoria (}(hjhhhNhNubj:)}(h``struct mm_sturct``h]hstruct mm_sturct}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh4: mm_user e mm_count), e nel codice dei filesystem (}(hjhhhNhNubj:)}(h``struct super_block``h]hstruct super_block}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh: s_count e s_active).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM hj9hhubh)}(hRicordatevi: se un altro thread può trovare la vostra struttura dati, e non avete un contatore di riferimenti per essa, quasi certamente avete un baco.h]hRicordatevi: se un altro thread può trovare la vostra struttura dati, e non avete un contatore di riferimenti per essa, quasi certamente avete un baco.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj9hhubeh}(h]strutture-datiah ]h"]11) strutture datiah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h12) Macro, enumerati e RTLh]h12) Macro, enumerati e RTL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubh)}(hkI nomi delle macro che definiscono delle costanti e le etichette degli enumerati sono scritte in maiuscolo.h]hkI nomi delle macro che definiscono delle costanti e le etichette degli enumerati sono scritte in maiuscolo.}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubjx)}(h#define CONSTANT 0x12345h]h#define CONSTANT 0x12345}hj3sbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMhjhhubh)}(hOGli enumerati sono da preferire quando si definiscono molte costanti correlate.h]hOGli enumerati sono da preferire quando si definiscono molte costanti correlate.}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hI nomi delle macro in MAIUSCOLO sono preferibili ma le macro che assomigliano a delle funzioni possono essere scritte in minuscolo.h]hI nomi delle macro in MAIUSCOLO sono preferibili ma le macro che assomigliano a delle funzioni possono essere scritte in minuscolo.}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM!hjhhubh)}(h\Generalmente, le funzioni inline sono preferibili rispetto alle macro che sembrano funzioni.h]h\Generalmente, le funzioni inline sono preferibili rispetto alle macro che sembrano funzioni.}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM$hjhhubh)}(h`Le macro che contengono più istruzioni dovrebbero essere sempre chiuse in un blocco do - while:h]h`Le macro che contengono più istruzioni dovrebbero essere sempre chiuse in un blocco do - while:}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM'hjhhubjx)}(h#define macrofun(a, b, c) \ do { \ if (a == 5) \ do_this(b, c); \ } while (0)h]h#define macrofun(a, b, c) \ do { \ if (a == 5) \ do_this(b, c); \ } while (0)}hjzsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhM*hjhhubh)}(hLe macro che sembrano funzioni con parametri non usati dovrebbero essere sostituite da funzioni inline per evitare il problema.h]hLe macro che sembrano funzioni con parametri non usati dovrebbero essere sostituite da funzioni inline per evitare il problema.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM2hjhhubjx)}(h+static inline void fun(struct foo *foo) { }h]h+static inline void fun(struct foo *foo) { }}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhM5hjhhubh)}(hX;Per motivi storici, molti file usano ancora l'approccio "cast a (void)" per valutare i parametri. Tuttavia, non è raccomandato. Le funzioni inline risolvono i problemi di "espressioni con effetti avversi valutate più di una volta", variabili non utilizzate, e in genere per qualche motivo sono documentate meglio.h]hXEPer motivi storici, molti file usano ancora l’approccio “cast a (void)” per valutare i parametri. Tuttavia, non è raccomandato. Le funzioni inline risolvono i problemi di “espressioni con effetti avversi valutate più di una volta”, variabili non utilizzate, e in genere per qualche motivo sono documentate meglio.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM;hjhhubjx)}(h/* * Avoid doing this whenever possible and instead opt for static * inline functions */ #define macrofun(foo) do { (void) (foo); } while (0)h]h/* * Avoid doing this whenever possible and instead opt for static * inline functions */ #define macrofun(foo) do { (void) (foo); } while (0)}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMAhjhhubh)}(h)Cose da evitare quando si usano le macro:h]h)Cose da evitare quando si usano le macro:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMIhjhhubj)}(hhh]j)}(h2le macro che hanno effetti sul flusso del codice: h]h)}(h1le macro che hanno effetti sul flusso del codice:h]h1le macro che hanno effetti sul flusso del codice:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhjhNubah}(h]h ]h"]h$]h&]j arabicj hj j uh1jhjhhhjhMKubjx)}(h#define FOO(x) \ do { \ if (blah(x) < 0) \ return -EBUGGERED; \ } while (0)h]h#define FOO(x) \ do { \ if (blah(x) < 0) \ return -EBUGGERED; \ } while (0)}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMMhjhhubh)}(hsono **proprio** una pessima idea. Sembra una chiamata a funzione ma termina la funzione chiamante; non cercate di rompere il decodificatore interno di chi legge il codice.h](hsono }(hjhhhNhNubj)}(h **proprio**h]hproprio}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh una pessima idea. Sembra una chiamata a funzione ma termina la funzione chiamante; non cercate di rompere il decodificatore interno di chi legge il codice.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMUhjhhubj)}(hhh]j)}(hLle macro che dipendono dall'uso di una variabile locale con un nome magico: h]h)}(hKle macro che dipendono dall'uso di una variabile locale con un nome magico:h]hMle macro che dipendono dall’uso di una variabile locale con un nome magico:}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMYhj%ubah}(h]h ]h"]h$]h&]uh1jhj"hhhjhNubah}(h]h ]h"]h$]h&]j jj hj j startKuh1jhjhhhjhMYubjx)}(h #define FOO(val) bar(index, val)h]h #define FOO(val) bar(index, val)}hjDsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhM[hjhhubh)}(hpotrebbe sembrare una bella cosa, ma è dannatamente confusionario quando uno legge il codice e potrebbe romperlo con una cambiamento che sembra innocente.h]hpotrebbe sembrare una bella cosa, ma è dannatamente confusionario quando uno legge il codice e potrebbe romperlo con una cambiamento che sembra innocente.}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM_hjhhubh)}(h3) le macro con argomenti che sono utilizzati come l-values; questo potrebbe ritorcervisi contro se qualcuno, per esempio, trasforma FOO in una funzione inline.h]h3) le macro con argomenti che sono utilizzati come l-values; questo potrebbe ritorcervisi contro se qualcuno, per esempio, trasforma FOO in una funzione inline.}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMbhjhhubh)}(h4) dimenticatevi delle precedenze: le macro che definiscono espressioni devono essere racchiuse fra parentesi. State attenti a problemi simili con le macro parametrizzate.h]h4) dimenticatevi delle precedenze: le macro che definiscono espressioni devono essere racchiuse fra parentesi. State attenti a problemi simili con le macro parametrizzate.}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMfhjhhubjx)}(h7#define CONSTANT 0x4000 #define CONSTEXP (CONSTANT | 3)h]h7#define CONSTANT 0x4000 #define CONSTEXP (CONSTANT | 3)}hj}sbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMjhjhhubh)}(hr5) collisione nello spazio dei nomi quando si definisce una variabile locale in una macro che sembra una funzione:h]hr5) collisione nello spazio dei nomi quando si definisce una variabile locale in una macro che sembra una funzione:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMohjhhubjx)}(h#define FOO(x) \ ({ \ typeof(x) ret; \ ret = calc_ret(x); \ (ret); \ })h]h#define FOO(x) \ ({ \ typeof(x) ret; \ ret = calc_ret(x); \ (ret); \ })}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMrhjhhubh)}(h~ret è un nome comune per una variabile locale - __foo_ret difficilmente andrà in conflitto con una variabile già esistente.h]h~ret è un nome comune per una variabile locale - __foo_ret difficilmente andrà in conflitto con una variabile già esistente.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM{hjhhubh)}(hIl manuale di cpp si occupa esaustivamente delle macro. Il manuale di sviluppo di gcc copre anche l'RTL che viene usato frequentemente nel kernel per il linguaggio assembler.h]hIl manuale di cpp si occupa esaustivamente delle macro. Il manuale di sviluppo di gcc copre anche l’RTL che viene usato frequentemente nel kernel per il linguaggio assembler.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM~hjhhubeh}(h]macro-enumerati-e-rtlah ]h"]12) macro, enumerati e rtlah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h&13) Visualizzare i messaggi del kernelh]h&13) Visualizzare i messaggi del kernel}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubh)}(hX"Agli sviluppatori del kernel piace essere visti come dotti. Tenete un occhio di riguardo per l'ortografia e farete una belle figura. In inglese, evitate l'uso incorretto di abbreviazioni come ``dont``: usate ``do not`` oppure ``don't``. Scrivete messaggi concisi, chiari, e inequivocabili.h](hAgli sviluppatori del kernel piace essere visti come dotti. Tenete un occhio di riguardo per l’ortografia e farete una belle figura. In inglese, evitate l’uso incorretto di abbreviazioni come }(hjhhhNhNubj:)}(h``dont``h]hdont}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh: usate }(hjhhhNhNubj:)}(h ``do not``h]hdo not}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh oppure }(hjhhhNhNubj:)}(h ``don't``h]hdon't}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh7. Scrivete messaggi concisi, chiari, e inequivocabili.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(h>I messaggi del kernel non devono terminare con un punto fermo.h]h>I messaggi del kernel non devono terminare con un punto fermo.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hcScrivere i numeri fra parentesi (%d) non migliora alcunché e per questo dovrebbero essere evitati.h]hcScrivere i numeri fra parentesi (%d) non migliora alcunché e per questo dovrebbero essere evitati.}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hX#Ci sono alcune macro per la diagnostica in che dovreste usare per assicurarvi che i messaggi vengano associati correttamente ai dispositivi e ai driver, e che siano etichettati correttamente: dev_err(), dev_warn(), dev_info(), e così via. Per messaggi che non sono associati ad alcun dispositivo, definisce pr_info(), pr_warn(), pr_err(), eccetera. Quando tutto funziona correttamente, non dovrebbero esserci stampe, per cui preferite dev_dbg/pr_debug a meno che non sia qualcosa di sbagliato da segnalare.h]hX#Ci sono alcune macro per la diagnostica in che dovreste usare per assicurarvi che i messaggi vengano associati correttamente ai dispositivi e ai driver, e che siano etichettati correttamente: dev_err(), dev_warn(), dev_info(), e così via. Per messaggi che non sono associati ad alcun dispositivo, definisce pr_info(), pr_warn(), pr_err(), eccetera. Quando tutto funziona correttamente, non dovrebbero esserci stampe, per cui preferite dev_dbg/pr_debug a meno che non sia qualcosa di sbagliato da segnalare.}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hXTirar fuori un buon messaggio di debug può essere una vera sfida; e quando l'avete può essere d'enorme aiuto per risolvere problemi da remoto. Tuttavia, i messaggi di debug sono gestiti differentemente rispetto agli altri. Le funzioni pr_XXX() stampano incondizionatamente ma pr_debug() no; essa non viene compilata nella configurazione predefinita, a meno che DEBUG o CONFIG_DYNAMIC_DEBUG non vengono impostati. Questo vale anche per dev_dbg() e in aggiunta VERBOSE_DEBUG per aggiungere i messaggi dev_vdbg().h]hXTirar fuori un buon messaggio di debug può essere una vera sfida; e quando l’avete può essere d’enorme aiuto per risolvere problemi da remoto. Tuttavia, i messaggi di debug sono gestiti differentemente rispetto agli altri. Le funzioni pr_XXX() stampano incondizionatamente ma pr_debug() no; essa non viene compilata nella configurazione predefinita, a meno che DEBUG o CONFIG_DYNAMIC_DEBUG non vengono impostati. Questo vale anche per dev_dbg() e in aggiunta VERBOSE_DEBUG per aggiungere i messaggi dev_vdbg().}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hXiMolti sottosistemi hanno delle opzioni di debug in Kconfig che aggiungono -DDEBUG nei corrispettivi Makefile, e in altri casi aggiungono #define DEBUG in specifici file. Infine, quando un messaggio di debug dev'essere stampato incondizionatamente, per esempio perché siete già in una sezione di debug racchiusa in #ifdef, potete usare printk(KERN_DEBUG ...).h]hXkMolti sottosistemi hanno delle opzioni di debug in Kconfig che aggiungono -DDEBUG nei corrispettivi Makefile, e in altri casi aggiungono #define DEBUG in specifici file. Infine, quando un messaggio di debug dev’essere stampato incondizionatamente, per esempio perché siete già in una sezione di debug racchiusa in #ifdef, potete usare printk(KERN_DEBUG ...).}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubeh}(h]"visualizzare-i-messaggi-del-kernelah ]h"]&13) visualizzare i messaggi del kernelah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h14) Assegnare memoriah]h14) Assegnare memoria}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jhjphhhjhMubh)}(hX$Il kernel fornisce i seguenti assegnatori ad uso generico: kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), e vzalloc(). Per maggiori informazioni, consultate la documentazione dell'API: :ref:`Documentation/translations/it_IT/core-api/memory-allocation.rst `h](hIl kernel fornisce i seguenti assegnatori ad uso generico: kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), e vzalloc(). Per maggiori informazioni, consultate la documentazione dell’API: }(hjhhhNhNubh)}(h]:ref:`Documentation/translations/it_IT/core-api/memory-allocation.rst `h]h)}(hjh]h?Documentation/translations/it_IT/core-api/memory-allocation.rst}(hjhhhNhNubah}(h]h ](hstdstd-refeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdochΌ refdomainjreftyperef refexplicitrefwarnhԌit_memory_allocationuh1hhjhMhjubeh}(h]h ]h"]h$]h&]uh1hhjhMhjphhubh)}(hLIl modo preferito per passare la dimensione di una struttura è il seguente:h]hLIl modo preferito per passare la dimensione di una struttura è il seguente:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjphhubjx)}(hp = kmalloc(sizeof(*p), ...);h]hp = kmalloc(sizeof(*p), ...);}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMhjphhubh)}(hLa forma alternativa, dove il nome della struttura viene scritto interamente, peggiora la leggibilità e introduce possibili bachi quando il tipo di puntatore cambia tipo ma il corrispondente sizeof non viene aggiornato.h]hLa forma alternativa, dove il nome della struttura viene scritto interamente, peggiora la leggibilità e introduce possibili bachi quando il tipo di puntatore cambia tipo ma il corrispondente sizeof non viene aggiornato.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjphhubh)}(hIl valore di ritorno è un puntatore void, effettuare un cast su di esso è ridondante. La conversione fra un puntatore void e un qualsiasi altro tipo di puntatore è garantito dal linguaggio di programmazione C.h]hIl valore di ritorno è un puntatore void, effettuare un cast su di esso è ridondante. La conversione fra un puntatore void e un qualsiasi altro tipo di puntatore è garantito dal linguaggio di programmazione C.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjphhubh)}(h:Il modo preferito per assegnare un vettore è il seguente:h]h:Il modo preferito per assegnare un vettore è il seguente:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjphhubjx)}(h'p = kmalloc_array(n, sizeof(...), ...);h]h'p = kmalloc_array(n, sizeof(...), ...);}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMhjphhubh)}(hAIl modo preferito per assegnare un vettore a zero è il seguente:h]hAIl modo preferito per assegnare un vettore a zero è il seguente:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjphhubjx)}(h!p = kcalloc(n, sizeof(...), ...);h]h!p = kcalloc(n, sizeof(...), ...);}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMhjphhubh)}(h|Entrambe verificano la condizione di overflow per la dimensione d'assegnamento n * sizeof(...), se accade ritorneranno NULL.h]h~Entrambe verificano la condizione di overflow per la dimensione d’assegnamento n * sizeof(...), se accade ritorneranno NULL.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjphhubh)}(hXQuesti allocatori generici producono uno *stack dump* in caso di fallimento a meno che non venga esplicitamente specificato __GFP_NOWARN. Quindi, nella maggior parte dei casi, è inutile stampare messaggi aggiuntivi quando uno di questi allocatori ritornano un puntatore NULL.h](h)Questi allocatori generici producono uno }(hj0hhhNhNubjS)}(h *stack dump*h]h stack dump}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1jRhj0ubh in caso di fallimento a meno che non venga esplicitamente specificato __GFP_NOWARN. Quindi, nella maggior parte dei casi, è inutile stampare messaggi aggiuntivi quando uno di questi allocatori ritornano un puntatore NULL.}(hj0hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjphhubeh}(h]assegnare-memoriaah ]h"]14) assegnare memoriaah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h15) Il morbo inlineh]h15) Il morbo inline}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjXhhhjhMubh)}(hXSembra che ci sia la percezione errata che gcc abbia una qualche magica opzione "rendimi più veloce" chiamata ``inline``. In alcuni casi l'uso di inline è appropriato (per esempio in sostituzione delle macro, vedi capitolo 12), ma molto spesso non lo è. L'uso abbondante della parola chiave inline porta ad avere un kernel più grande, che si traduce in un sistema nel suo complesso più lento per via di una cache per le istruzioni della CPU più grande e poi semplicemente perché ci sarà meno spazio disponibile per una pagina di cache. Pensateci un attimo; una fallimento nella cache causa una ricerca su disco che può tranquillamente richiedere 5 millisecondi. Ci sono TANTI cicli di CPU che potrebbero essere usati in questi 5 millisecondi.h](hsSembra che ci sia la percezione errata che gcc abbia una qualche magica opzione “rendimi più veloce” chiamata }(hjihhhNhNubj:)}(h ``inline``h]hinline}(hjqhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjiubhXz. In alcuni casi l’uso di inline è appropriato (per esempio in sostituzione delle macro, vedi capitolo 12), ma molto spesso non lo è. L’uso abbondante della parola chiave inline porta ad avere un kernel più grande, che si traduce in un sistema nel suo complesso più lento per via di una cache per le istruzioni della CPU più grande e poi semplicemente perché ci sarà meno spazio disponibile per una pagina di cache. Pensateci un attimo; una fallimento nella cache causa una ricerca su disco che può tranquillamente richiedere 5 millisecondi. Ci sono TANTI cicli di CPU che potrebbero essere usati in questi 5 millisecondi.}(hjihhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjXhhubh)}(hXSpesso le persone dicono che aggiungere inline a delle funzioni dichiarate static e utilizzare una sola volta è sempre una scelta vincente perché non ci sono altri compromessi. Questo è tecnicamente vero ma gcc è in grado di trasformare automaticamente queste funzioni in inline; i problemi di manutenzione del codice per rimuovere gli inline quando compare un secondo utente surclassano il potenziale vantaggio nel suggerire a gcc di fare una cosa che avrebbe fatto comunque.h]hXSpesso le persone dicono che aggiungere inline a delle funzioni dichiarate static e utilizzare una sola volta è sempre una scelta vincente perché non ci sono altri compromessi. Questo è tecnicamente vero ma gcc è in grado di trasformare automaticamente queste funzioni in inline; i problemi di manutenzione del codice per rimuovere gli inline quando compare un secondo utente surclassano il potenziale vantaggio nel suggerire a gcc di fare una cosa che avrebbe fatto comunque.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjXhhubeh}(h]il-morbo-inlineah ]h"]15) il morbo inlineah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h+16) Nomi e valori di ritorno delle funzionih]h+16) Nomi e valori di ritorno delle funzioni}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubh)}(hXILe funzioni possono ritornare diversi tipi di valori, e uno dei più comuni è quel valore che indica se una funzione ha completato con successo o meno. Questo valore può essere rappresentato come un codice di errore intero (-Exxx = fallimento, 0 = successo) oppure un booleano di successo (0 = fallimento, non-zero = successo).h]hXILe funzioni possono ritornare diversi tipi di valori, e uno dei più comuni è quel valore che indica se una funzione ha completato con successo o meno. Questo valore può essere rappresentato come un codice di errore intero (-Exxx = fallimento, 0 = successo) oppure un booleano di successo (0 = fallimento, non-zero = successo).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hXkMischiare questi due tipi di rappresentazioni è un terreno fertile per i bachi più insidiosi. Se il linguaggio C includesse una forte distinzione fra gli interi e i booleani, allora il compilatore potrebbe trovare questi errori per conto nostro ... ma questo non c'è. Per evitare di imbattersi in questo tipo di baco, seguite sempre la seguente convenzione::h]hXlMischiare questi due tipi di rappresentazioni è un terreno fertile per i bachi più insidiosi. Se il linguaggio C includesse una forte distinzione fra gli interi e i booleani, allora il compilatore potrebbe trovare questi errori per conto nostro ... ma questo non c’è. Per evitare di imbattersi in questo tipo di baco, seguite sempre la seguente convenzione:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubjx)}(hSe il nome di una funzione è un'azione o un comando imperativo, essa dovrebbe ritornare un codice di errore intero. Se il nome è un predicato, la funzione dovrebbe ritornare un booleano di "successo"h]hSe il nome di una funzione è un'azione o un comando imperativo, essa dovrebbe ritornare un codice di errore intero. Se il nome è un predicato, la funzione dovrebbe ritornare un booleano di "successo"}hjsbah}(h]h ]h"]h$]h&]jjuh1jwhjhMhjhhubh)}(hX'Per esempio, ``add work`` è un comando, e la funzione add_work() ritorna 0 in caso di successo o -EBUSY in caso di fallimento. Allo stesso modo, ``PCI device present`` è un predicato, e la funzione pci_dev_present() ritorna 1 se trova il dispositivo corrispondente con successo, altrimenti 0.h](h Per esempio, }(hjhhhNhNubj:)}(h ``add work``h]hadd work}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubhz è un comando, e la funzione add_work() ritorna 0 in caso di successo o -EBUSY in caso di fallimento. Allo stesso modo, }(hjhhhNhNubj:)}(h``PCI device present``h]hPCI device present}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh~ è un predicato, e la funzione pci_dev_present() ritorna 1 se trova il dispositivo corrispondente con successo, altrimenti 0.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hTutte le funzioni esportate (EXPORT) devono rispettare questa convenzione, e così dovrebbero anche tutte le funzioni pubbliche. Le funzioni private (static) possono non seguire questa convenzione, ma è comunque raccomandato che lo facciano.h]hTutte le funzioni esportate (EXPORT) devono rispettare questa convenzione, e così dovrebbero anche tutte le funzioni pubbliche. Le funzioni private (static) possono non seguire questa convenzione, ma è comunque raccomandato che lo facciano.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hXLe funzioni il cui valore di ritorno è il risultato di una computazione, piuttosto che l'indicazione sul successo di tale computazione, non sono soggette a questa regola. Solitamente si indicano gli errori ritornando un qualche valore fuori dai limiti. Un tipico esempio è quello delle funzioni che ritornano un puntatore; queste utilizzano NULL o ERR_PTR come meccanismo di notifica degli errori.h]hXLe funzioni il cui valore di ritorno è il risultato di una computazione, piuttosto che l’indicazione sul successo di tale computazione, non sono soggette a questa regola. Solitamente si indicano gli errori ritornando un qualche valore fuori dai limiti. Un tipico esempio è quello delle funzioni che ritornano un puntatore; queste utilizzano NULL o ERR_PTR come meccanismo di notifica degli errori.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubeh}(h]'nomi-e-valori-di-ritorno-delle-funzioniah ]h"]+16) nomi e valori di ritorno delle funzioniah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(h17) L'uso di boolh]h17) L’uso di bool}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0hhhjhM ubh)}(hXaNel kernel Linux il tipo bool deriva dal tipo _Bool dello standard C99. Un valore bool può assumere solo i valori 0 o 1, e implicitamente o esplicitamente la conversione a bool converte i valori in vero (*true*) o falso (*false*). Quando si usa un tipo bool il costrutto !! non sarà più necessario, e questo va ad eliminare una certa serie di bachi.h](hNel kernel Linux il tipo bool deriva dal tipo _Bool dello standard C99. Un valore bool può assumere solo i valori 0 o 1, e implicitamente o esplicitamente la conversione a bool converte i valori in vero (}(hjAhhhNhNubjS)}(h*true*h]htrue}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1jRhjAubh ) o falso (}(hjAhhhNhNubjS)}(h*false*h]hfalse}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1jRhjAubh|). Quando si usa un tipo bool il costrutto !! non sarà più necessario, e questo va ad eliminare una certa serie di bachi.}(hjAhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhj0hhubh)}(hpQuando si usano i valori booleani, dovreste utilizzare le definizioni di true e false al posto dei valori 1 e 0.h]hpQuando si usano i valori booleani, dovreste utilizzare le definizioni di true e false al posto dei valori 1 e 0.}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj0hhubh)}(hPer il valore di ritorno delle funzioni e per le variabili sullo stack, l'uso del tipo bool è sempre appropriato. L'uso di bool viene incoraggiato per migliorare la leggibilità e spesso è molto meglio di 'int' nella gestione di valori booleani.h]hXPer il valore di ritorno delle funzioni e per le variabili sullo stack, l’uso del tipo bool è sempre appropriato. L’uso di bool viene incoraggiato per migliorare la leggibilità e spesso è molto meglio di ‘int’ nella gestione di valori booleani.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj0hhubh)}(hX'Non usate bool se per voi sono importanti l'ordine delle righe di cache o la loro dimensione; la dimensione e l'allineamento cambia a seconda dell'architettura per la quale è stato compilato. Le strutture che sono state ottimizzate per l'allineamento o la dimensione non dovrebbero usare bool.h]hX/Non usate bool se per voi sono importanti l’ordine delle righe di cache o la loro dimensione; la dimensione e l’allineamento cambia a seconda dell’architettura per la quale è stato compilato. Le strutture che sono state ottimizzate per l’allineamento o la dimensione non dovrebbero usare bool.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhj0hhubh)}(hSe una struttura ha molti valori true/false, considerate l'idea di raggrupparli in un intero usando campi da 1 bit, oppure usate un tipo dalla larghezza fissa, come u8.h]hSe una struttura ha molti valori true/false, considerate l’idea di raggrupparli in un intero usando campi da 1 bit, oppure usate un tipo dalla larghezza fissa, come u8.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM!hj0hhubh)}(hCome per gli argomenti delle funzioni, molti valori true/false possono essere raggruppati in un singolo argomento a bit denominato 'flags'; spesso 'flags' è un'alternativa molto più leggibile se si hanno valori costanti per true/false.h]hCome per gli argomenti delle funzioni, molti valori true/false possono essere raggruppati in un singolo argomento a bit denominato ‘flags’; spesso ‘flags’ è un’alternativa molto più leggibile se si hanno valori costanti per true/false.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM%hj0hhubh)}(hoDetto ciò, un uso parsimonioso di bool nelle strutture dati e negli argomenti può migliorare la leggibilità.h]hoDetto ciò, un uso parsimonioso di bool nelle strutture dati e negli argomenti può migliorare la leggibilità.T}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM)hj0hhubeh}(h] l-uso-di-boolah ]h"]17) l'uso di boolah$]h&]uh1jhjhhhjhM ubj)}(hhh](j)}(h'18) Non reinventate le macro del kernelh]h'18) Non reinventate le macro del kernel}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhM-ubh)}(hIl file di intestazione include/linux/kernel.h contiene un certo numero di macro che dovreste usare piuttosto che implementarne una qualche variante. Per esempio, se dovete calcolare la lunghezza di un vettore, sfruttate la macro:h]hIl file di intestazione include/linux/kernel.h contiene un certo numero di macro che dovreste usare piuttosto che implementarne una qualche variante. Per esempio, se dovete calcolare la lunghezza di un vettore, sfruttate la macro:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM/hjhhubjx)}(h2#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))h]h2#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhM4hjhhubh)}(h[Analogamente, se dovete calcolare la dimensione di un qualche campo di una struttura, usateh]h[Analogamente, se dovete calcolare la dimensione di un qualche campo di una struttura, usate}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM8hjhhubjx)}(h/#define sizeof_field(t, f) (sizeof(((t*)0)->f))h]h/#define sizeof_field(t, f) (sizeof(((t*)0)->f))}hj sbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhM;hjhhubh)}(hCi sono anche le macro min() e max() che, se vi serve, effettuano un controllo rigido sui tipi. Sentitevi liberi di leggere attentamente questo file d'intestazione per scoprire cos'altro è stato definito che non dovreste reinventare nel vostro codice.h]hXCi sono anche le macro min() e max() che, se vi serve, effettuano un controllo rigido sui tipi. Sentitevi liberi di leggere attentamente questo file d’intestazione per scoprire cos’altro è stato definito che non dovreste reinventare nel vostro codice.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM?hjhhubeh}(h]#non-reinventate-le-macro-del-kernelah ]h"]'18) non reinventate le macro del kernelah$]h&]uh1jhjhhhjhM-ubj)}(hhh](j)}(h:19) Linee di configurazione degli editor e altre schifezzeh]h:19) Linee di configurazione degli editor e altre schifezze}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj0hhhjhMEubh)}(hAlcuni editor possono interpretare dei parametri di configurazione integrati nei file sorgenti e indicati con dai marcatori speciali. Per esempio, emacs interpreta le linee marcate nel seguente modo:h]hAlcuni editor possono interpretare dei parametri di configurazione integrati nei file sorgenti e indicati con dai marcatori speciali. Per esempio, emacs interpreta le linee marcate nel seguente modo:}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMGhj0hhubjx)}(h-*- mode: c -*-h]h-*- mode: c -*-}hjOsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMKhj0hhubh)}(hO come queste:h]hO come queste:}(hj^hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMOhj0hhubjx)}(hK/* Local Variables: compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" End: */h]hK/* Local Variables: compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" End: */}hjlsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMQhj0hhubh)}(h'Vim interpreta i marcatori come questi:h]h'Vim interpreta i marcatori come questi:}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMYhj0hhubjx)}(h/* vim:set sw=8 noet */h]h/* vim:set sw=8 noet */}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhM[hj0hhubh)}(hXNon includete nessuna di queste cose nei file sorgenti. Le persone hanno le proprie configurazioni personali per l'editor, e i vostri sorgenti non dovrebbero sovrascrivergliele. Questo vale anche per i marcatori d'indentazione e di modalità d'uso. Le persone potrebbero aver configurato una modalità su misura, oppure potrebbero avere qualche altra magia per far funzionare bene l'indentazione.h]hXNon includete nessuna di queste cose nei file sorgenti. Le persone hanno le proprie configurazioni personali per l’editor, e i vostri sorgenti non dovrebbero sovrascrivergliele. Questo vale anche per i marcatori d’indentazione e di modalità d’uso. Le persone potrebbero aver configurato una modalità su misura, oppure potrebbero avere qualche altra magia per far funzionare bene l’indentazione.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhM_hj0hhubeh}(h]6linee-di-configurazione-degli-editor-e-altre-schifezzeah ]h"]:19) linee di configurazione degli editor e altre schifezzeah$]h&]uh1jhjhhhjhMEubj)}(hhh](j)}(h20) Inline assemblyh]h20) Inline assembly}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMgubh)}(hXkNel codice specifico per un'architettura, potreste aver bisogno di codice *inline assembly* per interfacciarvi col processore o con una funzionalità specifica della piattaforma. Non esitate a farlo quando è necessario. Comunque, non usatele gratuitamente quando il C può fare la stessa cosa. Potete e dovreste punzecchiare l'hardware in C quando è possibile.h](hLNel codice specifico per un’architettura, potreste aver bisogno di codice }(hjhhhNhNubjS)}(h*inline assembly*h]hinline assembly}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jRhjubhX per interfacciarvi col processore o con una funzionalità specifica della piattaforma. Non esitate a farlo quando è necessario. Comunque, non usatele gratuitamente quando il C può fare la stessa cosa. Potete e dovreste punzecchiare l’hardware in C quando è possibile.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMihjhhubh)}(hConsiderate la scrittura di una semplice funzione che racchiude pezzi comuni di codice assembler piuttosto che continuare a riscrivere delle piccole varianti. Ricordatevi che l' *inline assembly* può utilizzare i parametri C.h](hConsiderate la scrittura di una semplice funzione che racchiude pezzi comuni di codice assembler piuttosto che continuare a riscrivere delle piccole varianti. Ricordatevi che l’ }(hjhhhNhNubjS)}(h*inline assembly*h]hinline assembly}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jRhjubh può utilizzare i parametri C.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMohjhhubh)}(hIl codice assembler più corposo e non banale dovrebbe andare nei file .S, coi rispettivi prototipi C definiti nei file d'intestazione. I prototipi C per le funzioni assembler dovrebbero usare ``asmlinkage``.h](hIl codice assembler più corposo e non banale dovrebbe andare nei file .S, coi rispettivi prototipi C definiti nei file d’intestazione. I prototipi C per le funzioni assembler dovrebbero usare }(hjhhhNhNubj:)}(h``asmlinkage``h]h asmlinkage}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMshjhhubh)}(hPotreste aver bisogno di marcare il vostro codice asm come volatile al fine d'evitare che GCC lo rimuova quando pensa che non ci siano effetti collaterali. Non c'è sempre bisogno di farlo, e farlo quando non serve limita le ottimizzazioni.h]hPotreste aver bisogno di marcare il vostro codice asm come volatile al fine d’evitare che GCC lo rimuova quando pensa che non ci siano effetti collaterali. Non c’è sempre bisogno di farlo, e farlo quando non serve limita le ottimizzazioni.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMwhjhhubh)}(hX,Quando scrivete una singola espressione *inline assembly* contenente più istruzioni, mettete ognuna di queste istruzioni in una stringa e riga diversa; ad eccezione dell'ultima stringa/istruzione, ognuna deve terminare con ``\n\t`` al fine di allineare correttamente l'assembler che verrà generato:h](h(Quando scrivete una singola espressione }(hj-hhhNhNubjS)}(h*inline assembly*h]hinline assembly}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1jRhj-ubh contenente più istruzioni, mettete ognuna di queste istruzioni in una stringa e riga diversa; ad eccezione dell’ultima stringa/istruzione, ognuna deve terminare con }(hj-hhhNhNubj:)}(h``\n\t``h]h\n\t}(hjGhhhNhNubah}(h]h ]h"]h$]h&]uh1j9hj-ubhF al fine di allineare correttamente l’assembler che verrà generato:}(hj-hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhM|hjhhubjx)}(hqasm ("magic %reg1, #42\n\t" "more_magic %reg2, %reg3" : /* outputs */ : /* inputs */ : /* clobbers */);h]hqasm ("magic %reg1, #42\n\t" "more_magic %reg2, %reg3" : /* outputs */ : /* inputs */ : /* clobbers */);}hj_sbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMhjhhubeh}(h]inline-assemblyah ]h"]20) inline assemblyah$]h&]uh1jhjhhhjhMgubj)}(hhh](j)}(h!21) Compilazione sotto condizioneh]h!21) Compilazione sotto condizione}(hjyhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjvhhhjhMubh)}(hXOvunque sia possibile, non usate le direttive condizionali del preprocessore (#if, #ifdef) nei file .c; farlo rende il codice difficile da leggere e da seguire. Invece, usate queste direttive nei file d'intestazione per definire le funzioni usate nei file .c, fornendo i relativi stub nel caso #else, e quindi chiamate queste funzioni senza condizioni di preprocessore. Il compilatore non produrrà alcun codice per le funzioni stub, produrrà gli stessi risultati, e la logica rimarrà semplice da seguire.h]hXOvunque sia possibile, non usate le direttive condizionali del preprocessore (#if, #ifdef) nei file .c; farlo rende il codice difficile da leggere e da seguire. Invece, usate queste direttive nei file d’intestazione per definire le funzioni usate nei file .c, fornendo i relativi stub nel caso #else, e quindi chiamate queste funzioni senza condizioni di preprocessore. Il compilatore non produrrà alcun codice per le funzioni stub, produrrà gli stessi risultati, e la logica rimarrà semplice da seguire.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjvhhubh)}(hX È preferibile non compilare intere funzioni piuttosto che porzioni d'esse o porzioni d'espressioni. Piuttosto che mettere una ifdef in un'espressione, fattorizzate parte dell'espressione, o interamente, in funzioni e applicate la direttiva condizionale su di esse.h]hXÈ preferibile non compilare intere funzioni piuttosto che porzioni d’esse o porzioni d’espressioni. Piuttosto che mettere una ifdef in un’espressione, fattorizzate parte dell’espressione, o interamente, in funzioni e applicate la direttiva condizionale su di esse.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjvhhubh)}(hXrSe avete una variabile o funzione che potrebbe non essere usata in alcune configurazioni, e quindi il compilatore potrebbe avvisarvi circa la definizione inutilizzata, marcate questa definizione come __maybe_unused piuttosto che racchiuderla in una direttiva condizionale del preprocessore. (Comunque, se una variabile o funzione è *sempre* inutilizzata, rimuovetela).h](hXNSe avete una variabile o funzione che potrebbe non essere usata in alcune configurazioni, e quindi il compilatore potrebbe avvisarvi circa la definizione inutilizzata, marcate questa definizione come __maybe_unused piuttosto che racchiuderla in una direttiva condizionale del preprocessore. (Comunque, se una variabile o funzione è }(hjhhhNhNubjS)}(h*sempre*h]hsempre}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jRhjubh inutilizzata, rimuovetela).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjvhhubh)}(hNel codice, dov'è possibile, usate la macro IS_ENABLED per convertire i simboli Kconfig in espressioni booleane C, e quindi usatela nelle classiche condizioni C:h]hNel codice, dov’è possibile, usate la macro IS_ENABLED per convertire i simboli Kconfig in espressioni booleane C, e quindi usatela nelle classiche condizioni C:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjvhhubjx)}(h1if (IS_ENABLED(CONFIG_SOMETHING)) { ... }h]h1if (IS_ENABLED(CONFIG_SOMETHING)) { ... }}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMhjvhhubh)}(hXIl compilatore valuterà la condizione come costante (constant-fold), e quindi includerà o escluderà il blocco di codice come se fosse in un #ifdef, quindi non ne aumenterà il tempo di esecuzione. Tuttavia, questo permette al compilatore C di vedere il codice nel blocco condizionale e verificarne la correttezza (sintassi, tipi, riferimenti ai simboli, eccetera). Quindi dovete comunque utilizzare #ifdef se il codice nel blocco condizionale esiste solo quando la condizione è soddisfatta.h]hXIl compilatore valuterà la condizione come costante (constant-fold), e quindi includerà o escluderà il blocco di codice come se fosse in un #ifdef, quindi non ne aumenterà il tempo di esecuzione. Tuttavia, questo permette al compilatore C di vedere il codice nel blocco condizionale e verificarne la correttezza (sintassi, tipi, riferimenti ai simboli, eccetera). Quindi dovete comunque utilizzare #ifdef se il codice nel blocco condizionale esiste solo quando la condizione è soddisfatta.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjvhhubh)}(hAlla fine di un blocco corposo di #if o #ifdef (più di alcune linee), mettete un commento sulla stessa riga di #endif, annotando la condizione che termina. Per esempio:h]hAlla fine di un blocco corposo di #if o #ifdef (più di alcune linee), mettete un commento sulla stessa riga di #endif, annotando la condizione che termina. Per esempio:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjvhhubjx)}(h9#ifdef CONFIG_SOMETHING ... #endif /* CONFIG_SOMETHING */h]h9#ifdef CONFIG_SOMETHING ... #endif /* CONFIG_SOMETHING */}hjsbah}(h]h ]h"]h$]h&]jjjjjj}uh1jwhjhMhjvhhubeh}(h]compilazione-sotto-condizioneah ]h"]!21) compilazione sotto condizioneah$]h&]uh1jhjhhhjhMubj)}(hhh](j)}(hAppendice I) riferimentih]hAppendice I) riferimenti}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhjhMubh)}(hThe C Programming Language, Second Edition by Brian W. Kernighan and Dennis M. Ritchie. Prentice Hall, Inc., 1988. ISBN 0-13-110362-8 (paperback), 0-13-110370-9 (hardback).h]hThe C Programming Language, Second Edition by Brian W. Kernighan and Dennis M. Ritchie. Prentice Hall, Inc., 1988. ISBN 0-13-110362-8 (paperback), 0-13-110370-9 (hardback).}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hoThe Practice of Programming by Brian W. Kernighan and Rob Pike. Addison-Wesley, Inc., 1999. ISBN 0-201-61586-X.h]hoThe Practice of Programming by Brian W. Kernighan and Rob Pike. Addison-Wesley, Inc., 1999. ISBN 0-201-61586-X.}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hManuali GNU - nei casi in cui sono compatibili con K&R e questo documento - per indent, cpp, gcc e i suoi dettagli interni, tutto disponibile qui https://www.gnu.org/manual/h](hManuali GNU - nei casi in cui sono compatibili con K&R e questo documento - per indent, cpp, gcc e i suoi dettagli interni, tutto disponibile qui }(hj@hhhNhNubjZ)}(hhttps://www.gnu.org/manual/h]hhttps://www.gnu.org/manual/}(hjHhhhNhNubah}(h]h ]h"]h$]h&]refurijJuh1jYhj@ubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hxWG14 è il gruppo internazionale di standardizzazione per il linguaggio C, URL: https://www.open-std.org/JTC1/SC22/WG14/h](hPWG14 è il gruppo internazionale di standardizzazione per il linguaggio C, URL: }(hj]hhhNhNubjZ)}(h(https://www.open-std.org/JTC1/SC22/WG14/h]h(https://www.open-std.org/JTC1/SC22/WG14/}(hjehhhNhNubah}(h]h ]h"]h$]h&]refurijguh1jYhj]ubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubh)}(hzKernel CodingStyle, by greg@kroah.com at OLS 2002: http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/h](hKernel CodingStyle, by }(hjzhhhNhNubjZ)}(hgreg@kroah.comh]hgreg@kroah.com}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:greg@kroah.comuh1jYhjzubh at OLS 2002: }(hjzhhhNhNubjZ)}(hGhttp://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/h]hGhttp://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jYhjzubeh}(h]h ]h"]h$]h&]uh1hhjhMhjhhubeh}(h]appendice-i-riferimentiah ]h"]appendice i) riferimentiah$]h&]uh1jhjhhhjhMubeh}(h]($stile-del-codice-per-il-kernel-linuxjeh ]h"]($stile del codice per il kernel linuxit_codingstyleeh$]h&]uh1jhhhhhjhK expect_referenced_by_name}jjsexpect_referenced_by_id}jjsubeh}(h]h ]h"]h$]h&]sourcejuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcej _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}j]jasnameids}(jjjjjjjj~jjjjjjj j jjj j j j jjjIjFjjj6j3jjjjjmjjjUjRjjj-j*jjj-j*jjjsjpjj jju nametypes}(jjjjjjjj jj j jjIjj6jjjmjUjj-jj-jjsjjuh}(jjjjjjj~jjjjj jjj jjj j j~ j j jj jFjjjLj3jjj9jjjjjjRjpjjXj*jjj0j*jjj0jpjj jvjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]hsystem_message)}(hhh]h)}(h:Enumerated list start value not ordinal-1: "2" (ordinal 2)h]h>Enumerated list start value not ordinal-1: “2” (ordinal 2)}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjHubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcejlineK uh1jFhjhhhjhMYubatransform_messages]jG)}(hhh]h)}(hhh]h4Hyperlink target "it-codingstyle" is not referenced.}hjisbah}(h]h ]h"]h$]h&]uh1hhjfubah}(h]h ]h"]h$]h&]levelKtypejasourcejlineKuh1jFuba transformerN include_log]9Documentation/translations/it_IT/process/coding-style.rst(NNNNta decorationNhhub.