1181643Skmacy.. include:: ../disclaimer-ita.rst
2181643Skmacy
3181643Skmacy:Original: :ref:`Documentation/process/coding-style.rst <codingstyle>`
4181643Skmacy:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
5181643Skmacy
6181643Skmacy.. _it_codingstyle:
7181643Skmacy
8181643SkmacyStile del codice per il kernel Linux
9181643Skmacy====================================
10181643Skmacy
11181643SkmacyQuesto �� un breve documento che descrive lo stile di codice preferito per
12181643Skmacyil kernel Linux.  Lo stile di codifica �� molto personale e non voglio
13181643Skmacy**forzare** nessuno ad accettare il mio, ma questo stile �� quello che
14181643Skmacydev'essere usato per qualsiasi cosa che io sia in grado di mantenere, e l'ho
15181643Skmacypreferito anche per molte altre cose.  Per favore, almeno tenete in
16181643Skmacyconsiderazione le osservazioni espresse qui.
17181643Skmacy
18181643SkmacyLa prima cosa che suggerisco �� quella di stamparsi una copia degli standard
19181643Skmacydi codifica GNU e di NON leggerla.  Bruciatela, �� un grande gesto simbolico.
20181643Skmacy
21181643SkmacyComunque, ecco i punti:
22181643Skmacy
23181643Skmacy1) Indentazione
24181643Skmacy---------------
25181643Skmacy
26181643SkmacyLa tabulazione (tab) �� di 8 caratteri e cos�� anche le indentazioni. Ci sono
27181643Skmacyalcuni movimenti di eretici che vorrebbero l'indentazione a 4 (o perfino 2!)
28181643Skmacycaratteri di profondit��, che �� simile al tentativo di definire il valore del
29181643Skmacypi-greco a 3.
30181643Skmacy
31181643SkmacyMotivazione: l'idea dell'indentazione �� di definire chiaramente dove un blocco
32181643Skmacydi controllo inizia e finisce.  Specialmente quando siete rimasti a guardare lo
33181643Skmacyschermo per 20 ore a file, troverete molto pi�� facile capire i livelli di
34181643Skmacyindentazione se questi sono larghi.
35181643Skmacy
36181643SkmacyOra, alcuni rivendicano che un'indentazione da 8 caratteri sposta il codice
37181643Skmacytroppo a destra e che quindi rende difficile la lettura su schermi a 80
38181643Skmacycaratteri.  La risposta a questa affermazione �� che se vi servono pi�� di 3
39181643Skmacylivelli di indentazione, siete comunque fregati e dovreste correggere il vostro
40181643Skmacyprogramma.
41181643Skmacy
42181643SkmacyIn breve, l'indentazione ad 8 caratteri rende pi�� facile la lettura, e in
43181643Skmacyaggiunta vi avvisa quando state annidando troppo le vostre funzioni.
44181643SkmacyTenete ben a mente questo avviso.
45181643Skmacy
46181643SkmacyAl fine di facilitare l'indentazione del costrutto switch, si preferisce
47181643Skmacyallineare sulla stessa colonna la parola chiave ``switch`` e i suoi
48181643Skmacysubordinati ``case``. In questo modo si evita una doppia indentazione per
49181643Skmacyi ``case``.  Un esempio.:
50181643Skmacy
51181643Skmacy.. code-block:: c
52181643Skmacy
53181643Skmacy	switch (suffix) {
54181643Skmacy	case 'G':
55181643Skmacy	case 'g':
56181643Skmacy		mem <<= 30;
57181643Skmacy		break;
58181643Skmacy	case 'M':
59181643Skmacy	case 'm':
60181643Skmacy		mem <<= 20;
61181643Skmacy		break;
62181643Skmacy	case 'K':
63181643Skmacy	case 'k':
64181643Skmacy		mem <<= 10;
65181643Skmacy		fallthrough;
66181643Skmacy	default:
67181643Skmacy		break;
68181643Skmacy	}
69181643Skmacy
70181643SkmacyA meno che non vogliate nascondere qualcosa, non mettete pi�� istruzioni sulla
71181643Skmacystessa riga:
72181643Skmacy
73181643Skmacy.. code-block:: c
74181643Skmacy
75181643Skmacy	if (condition) do_this;
76181643Skmacy	  do_something_everytime;
77181643Skmacy
78181643SkmacyNon usate le virgole per evitare le parentesi:
79181643Skmacy
80181643Skmacy.. code-block:: c
81181643Skmacy
82181643Skmacy	if (condition)
83181643Skmacy               do_this(), do_that();
84181643Skmacy
85181643SkmacyInvece, usate sempre le parentesi per racchiudere pi�� istruzioni.
86181643Skmacy
87181643Skmacy.. code-block:: c
88181643Skmacy
89181643Skmacy	if (condition) {
90181643Skmacy               do_this();
91181643Skmacy               do_that();
92181643Skmacy       }
93181643Skmacy
94181643SkmacyNon mettete nemmeno pi�� assegnamenti sulla stessa riga.  Lo stile del kernel
95181643Skmacy�� ultrasemplice.  Evitate espressioni intricate.
96181643Skmacy
97181643Skmacy
98181643SkmacyAl di fuori dei commenti, della documentazione ed escludendo i Kconfig, gli
99181643Skmacyspazi non vengono mai usati per l'indentazione, e l'esempio qui sopra ��
100181643Skmacyvolutamente errato.
101181643Skmacy
102181643SkmacyProcuratevi un buon editor di testo e non lasciate spazi bianchi alla fine
103181643Skmacydelle righe.
104181643Skmacy
105181643Skmacy
106181643Skmacy2) Spezzare righe lunghe e stringhe
107181643Skmacy-----------------------------------
108181643Skmacy
109181643SkmacyLo stile del codice riguarda la leggibilit�� e la manutenibilit�� utilizzando
110181643Skmacystrumenti comuni.
111181643Skmacy
112181643SkmacyCome limite di riga si preferiscono le 80 colonne.
113181643Skmacy
114181643SkmacyEspressioni pi�� lunghe di 80 colonne dovrebbero essere spezzettate in
115181643Skmacypezzi pi�� piccoli, a meno che eccedere le 80 colonne non aiuti ad
116181643Skmacyaumentare la leggibilit�� senza nascondere informazioni.
117181643Skmacy
118181643SkmacyI nuovi pezzi derivati sono sostanzialmente pi�� corti degli originali
119181643Skmacye vengono posizionati pi�� a destra. Uno stile molto comune �� quello di
120181643Skmacyallineare i nuovi pezzi alla parentesi aperta di una funzione.
121181643Skmacy
122181643SkmacyLo stesso si applica, nei file d'intestazione, alle funzioni con una
123181643Skmacylista di argomenti molto lunga.
124181643Skmacy
125181643SkmacyTuttavia, non spezzettate mai le stringhe visibili agli utenti come i
126181643Skmacymessaggi di printk, questo perch�� inibireste la possibilit��
127181643Skmacyd'utilizzare grep per cercarle.
128181643Skmacy
129181643Skmacy3) Posizionamento di parentesi graffe e spazi
130181643Skmacy---------------------------------------------
131181643Skmacy
132181643SkmacyUn altro problema che s'affronta sempre quando si parla di stile in C ��
133181643Skmacyil posizionamento delle parentesi graffe.  Al contrario della dimensione
134181643Skmacydell'indentazione, non ci sono motivi tecnici sulla base dei quali scegliere
135181643Skmacyuna strategia di posizionamento o un'altra; ma il modo qui preferito,
136181643Skmacycome mostratoci dai profeti Kernighan e Ritchie, �� quello di
137181643Skmacyposizionare la parentesi graffa di apertura per ultima sulla riga, e quella
138181643Skmacydi chiusura per prima su una nuova riga, cos��:
139181643Skmacy
140181643Skmacy.. code-block:: c
141181643Skmacy
142181643Skmacy	if (x is true) {
143181643Skmacy		we do y
144181643Skmacy	}
145181643Skmacy
146181643SkmacyQuesto �� valido per tutte le espressioni che non siano funzioni (if, switch,
147181643Skmacyfor, while, do).  Per esempio:
148181643Skmacy
149181643Skmacy.. code-block:: c
150181643Skmacy
151181643Skmacy	switch (action) {
152181643Skmacy	case KOBJ_ADD:
153181643Skmacy		return "add";
154181643Skmacy	case KOBJ_REMOVE:
155181643Skmacy		return "remove";
156181643Skmacy	case KOBJ_CHANGE:
157181643Skmacy		return "change";
158181643Skmacy	default:
159181643Skmacy		return NULL;
160181643Skmacy	}
161181643Skmacy
162181643SkmacyTuttavia, c'�� il caso speciale, le funzioni: queste hanno la parentesi graffa
163181643Skmacydi apertura all'inizio della riga successiva, quindi:
164181643Skmacy
165181643Skmacy.. code-block:: c
166181643Skmacy
167181643Skmacy	int function(int x)
168181643Skmacy	{
169181643Skmacy		body of function
170181643Skmacy	}
171181643Skmacy
172181643SkmacyEretici da tutto il mondo affermano che questa incoerenza �� ...
173181643Skmacyinsomma ... incoerente, ma tutte le persone ragionevoli sanno che (a)
174181643SkmacyK&R hanno **ragione** e (b) K&R hanno ragione.  A parte questo, le funzioni
175181643Skmacysono comunque speciali (non potete annidarle in C).
176181643Skmacy
177181643SkmacyNotate che la graffa di chiusura �� da sola su una riga propria, ad
178181643Skmacy**eccezione** di quei casi dove �� seguita dalla continuazione della stessa
179181643Skmacyespressione, in pratica ``while`` nell'espressione do-while, oppure ``else``
180181643Skmacynell'espressione if-else, come questo:
181181643Skmacy
182181643Skmacy.. code-block:: c
183181643Skmacy
184181643Skmacy	do {
185181643Skmacy		body of do-loop
186181643Skmacy	} while (condition);
187181643Skmacy
188181643Skmacye
189181643Skmacy
190181643Skmacy.. code-block:: c
191181643Skmacy
192181643Skmacy	if (x == y) {
193181643Skmacy		..
194181643Skmacy	} else if (x > y) {
195181643Skmacy		...
196181643Skmacy	} else {
197181643Skmacy		....
198181643Skmacy	}
199181643Skmacy
200181643SkmacyMotivazione: K&R.
201181643Skmacy
202181643SkmacyInoltre, notate che questo posizionamento delle graffe minimizza il numero
203181643Skmacydi righe vuote senza perdere di leggibilit��.  In questo modo, dato che le
204181643Skmacyrighe sul vostro schermo non sono una risorsa illimitata (pensate ad uno
205181643Skmacyterminale con 25 righe), avrete delle righe vuote da riempire con dei
206181643Skmacycommenti.
207181643Skmacy
208181643SkmacyNon usate inutilmente le graffe dove una singola espressione �� sufficiente.
209181643Skmacy
210181643Skmacy.. code-block:: c
211181643Skmacy
212181643Skmacy	if (condition)
213181643Skmacy		action();
214181643Skmacy
215181643Skmacye
216181643Skmacy
217181643Skmacy.. code-block:: none
218181643Skmacy
219181643Skmacy	if (condition)
220181643Skmacy		do_this();
221181643Skmacy	else
222181643Skmacy		do_that();
223181643Skmacy
224181643SkmacyQuesto non vale nel caso in cui solo un ramo dell'espressione if-else
225181643Skmacycontiene una sola espressione; in quest'ultimo caso usate le graffe per
226181643Skmacyentrambe i rami:
227181643Skmacy
228181643Skmacy.. code-block:: c
229181643Skmacy
230181643Skmacy	if (condition) {
231181643Skmacy		do_this();
232181643Skmacy		do_that();
233181643Skmacy	} else {
234181643Skmacy		otherwise();
235181643Skmacy	}
236181643Skmacy
237181643SkmacyInoltre, usate le graffe se un ciclo contiene pi�� di una semplice istruzione:
238181643Skmacy
239181643Skmacy.. code-block:: c
240181643Skmacy
241181643Skmacy	while (condition) {
242181643Skmacy		if (test)
243181643Skmacy			do_something();
244181643Skmacy	}
245181643Skmacy
246181643Skmacy3.1) Spazi
247181643Skmacy**********
248181643Skmacy
249181643SkmacyLo stile del kernel Linux per quanto riguarda gli spazi, dipende
250181643Skmacy(principalmente) dalle funzioni e dalle parole chiave.  Usate una spazio dopo
251181643Skmacy(quasi tutte) le parole chiave.  L'eccezioni pi�� evidenti sono sizeof, typeof,
252181643Skmacyalignof, e __attribute__, il cui aspetto �� molto simile a quello delle
253181643Skmacyfunzioni (e in Linux, solitamente, sono usate con le parentesi, anche se il
254181643Skmacylinguaggio non lo richiede; come ``sizeof info`` dopo aver dichiarato
255181643Skmacy``struct fileinfo info``).
256181643Skmacy
257181643SkmacyQuindi utilizzate uno spazio dopo le seguenti parole chiave::
258181643Skmacy
259181643Skmacy	if, switch, case, for, do, while
260181643Skmacy
261181643Skmacyma non con sizeof, typeof, alignof, o __attribute__.  Ad esempio,
262181643Skmacy
263181643Skmacy.. code-block:: c
264181643Skmacy
265181643Skmacy
266181643Skmacy	s = sizeof(struct file);
267181643Skmacy
268181643SkmacyNon aggiungete spazi attorno (dentro) ad un'espressione fra parentesi. Questo
269181643Skmacyesempio �� **brutto**:
270181643Skmacy
271181643Skmacy.. code-block:: c
272181643Skmacy
273181643Skmacy
274181643Skmacy	s = sizeof( struct file );
275181643Skmacy
276181643SkmacyQuando dichiarate un puntatore ad una variabile o una funzione che ritorna un
277181643Skmacypuntatore, il posto suggerito per l'asterisco ``*`` �� adiacente al nome della
278181643Skmacyvariabile o della funzione, e non adiacente al nome del tipo. Esempi:
279181643Skmacy
280181643Skmacy.. code-block:: c
281181643Skmacy
282181643Skmacy
283181643Skmacy	char *linux_banner;
284181643Skmacy	unsigned long long memparse(char *ptr, char **retptr);
285181643Skmacy	char *match_strdup(substring_t *s);
286181643Skmacy
287181643SkmacyUsate uno spazio attorno (da ogni parte) alla maggior parte degli operatori
288181643Skmacybinari o ternari, come i seguenti::
289181643Skmacy
290181643Skmacy	=  +  -  <  >  *  /  %  |  &  ^  <=  >=  ==  !=  ?  :
291181643Skmacy
292181643Skmacyma non mettete spazi dopo gli operatori unari::
293181643Skmacy
294181643Skmacy	&  *  +  -  ~  !  sizeof  typeof  alignof  __attribute__  defined
295181643Skmacy
296181643Skmacynessuno spazio dopo l'operatore unario suffisso di incremento o decremento::
297181643Skmacy
298181643Skmacy	++  --
299181643Skmacy
300181643Skmacynessuno spazio dopo l'operatore unario prefisso di incremento o decremento::
301181643Skmacy
302181643Skmacy	++  --
303181643Skmacy
304181643Skmacye nessuno spazio attorno agli operatori dei membri di una struttura ``.`` e
305181643Skmacy``->``.
306181643Skmacy
307181643SkmacyNon lasciate spazi bianchi alla fine delle righe.  Alcuni editor con
308181643Skmacyl'indentazione ``furba`` inseriranno gli spazi bianchi all'inizio di una nuova
309181643Skmacyriga in modo appropriato, quindi potrete scrivere la riga di codice successiva
310181643Skmacyimmediatamente.  Tuttavia, alcuni di questi stessi editor non rimuovono
311181643Skmacyquesti spazi bianchi quando non scrivete nulla sulla nuova riga, ad esempio
312181643Skmacyperch�� volete lasciare una riga vuota.  Il risultato �� che finirete per avere
313181643Skmacydelle righe che contengono spazi bianchi in coda.
314181643Skmacy
315181643SkmacyGit vi avviser�� delle modifiche che aggiungono questi spazi vuoti di fine riga,
316181643Skmacye pu�� opzionalmente rimuoverli per conto vostro; tuttavia, se state applicando
317181643Skmacyuna serie di modifiche, questo potrebbe far fallire delle modifiche successive
318181643Skmacyperch�� il contesto delle righe verr�� cambiato.
319181643Skmacy
320181643Skmacy4) Assegnare nomi
321181643Skmacy-----------------
322181643Skmacy
323181643SkmacyC �� un linguaggio spartano, e cos�� dovrebbero esserlo i vostri nomi.  Al
324181643Skmacycontrario dei programmatori Modula-2 o Pascal, i programmatori C non usano
325181643Skmacynomi graziosi come ThisVariableIsATemporaryCounter.  Un programmatore C
326181643Skmacychiamerebbe questa variabile ``tmp``, che �� molto pi�� facile da scrivere e
327181643Skmacynon �� una delle pi�� difficili da capire.
328181643Skmacy
329181643SkmacyTUTTAVIA, nonostante i nomi con notazione mista siano da condannare, i nomi
330181643Skmacydescrittivi per variabili globali sono un dovere.  Chiamare una funzione
331181643Skmacyglobale ``pippo`` �� un insulto.
332181643Skmacy
333181643SkmacyLe variabili GLOBALI (da usare solo se vi servono **davvero**) devono avere
334181643Skmacydei nomi descrittivi, cos�� come le funzioni globali.  Se avete una funzione
335181643Skmacyche conta gli utenti attivi, dovreste chiamarla ``count_active_users()`` o
336181643Skmacyqualcosa di simile, **non** dovreste chiamarla ``cntusr()``.
337181643Skmacy
338181643SkmacyCodificare il tipo di funzione nel suo nome (quella cosa chiamata notazione
339181643Skmacyungherese) �� stupido - il compilatore conosce comunque il tipo e
340181643Skmacypu�� verificarli, e inoltre confonde i programmatori.
341181643Skmacy
342181643SkmacyLe variabili LOCALI dovrebbero avere nomi corti, e significativi.  Se avete
343181643Skmacyun qualsiasi contatore di ciclo, probabilmente sar�� chiamato ``i``.
344181643SkmacyChiamarlo ``loop_counter`` non �� produttivo, non ci sono possibilit�� che
345181643Skmacy``i`` possa non essere capito.  Analogamente, ``tmp`` pu�� essere una qualsiasi
346181643Skmacyvariabile che viene usata per salvare temporaneamente un valore.
347181643Skmacy
348181643SkmacySe avete paura di fare casino coi nomi delle vostre variabili locali, allora
349181643Skmacyavete un altro problema che �� chiamato sindrome dello squilibrio dell'ormone
350181643Skmacydella crescita delle funzioni. Vedere il capitolo 6 (funzioni).
351181643Skmacy
352181643Skmacy5) Definizione di tipi (typedef)
353181643Skmacy--------------------------------
354181643Skmacy
355181643SkmacyPer favore non usate cose come ``vps_t``.
356181643SkmacyUsare il typedef per strutture e puntatori �� uno **sbaglio**. Quando vedete:
357181643Skmacy
358181643Skmacy.. code-block:: c
359181643Skmacy
360181643Skmacy	vps_t a;
361181643Skmacy
362181643Skmacynei sorgenti, cosa significa?
363181643SkmacySe, invece, dicesse:
364181643Skmacy
365181643Skmacy.. code-block:: c
366181643Skmacy
367181643Skmacy	struct virtual_container *a;
368181643Skmacy
369181643Skmacypotreste dire cos'�� effettivamente ``a``.
370181643Skmacy
371181643SkmacyMolte persone pensano che la definizione dei tipi ``migliori la leggibilit��``.
372181643SkmacyNon molto. Sono utili per:
373181643Skmacy
374181643Skmacy (a) gli oggetti completamente opachi (dove typedef viene proprio usato allo
375181643Skmacy     scopo di **nascondere** cosa sia davvero l'oggetto).
376181643Skmacy
377181643Skmacy     Esempio: ``pte_t`` eccetera sono oggetti opachi che potete usare solamente
378181643Skmacy     con le loro funzioni accessorie.
379181643Skmacy
380181643Skmacy     .. note::
381181643Skmacy       Gli oggetti opachi e le ``funzioni accessorie`` non sono, di per se,
382181643Skmacy       una bella cosa. Il motivo per cui abbiamo cose come pte_t eccetera ��
383181643Skmacy       che davvero non c'�� alcuna informazione portabile.
384181643Skmacy
385181643Skmacy (b) i tipi chiaramente interi, dove l'astrazione **aiuta** ad evitare
386181643Skmacy     confusione sul fatto che siano ``int`` oppure ``long``.
387181643Skmacy
388181643Skmacy     u8/u16/u32 sono typedef perfettamente accettabili, anche se ricadono
389181643Skmacy     nella categoria (d) piuttosto che in questa.
390181643Skmacy
391181643Skmacy     .. note::
392181643Skmacy
393181643Skmacy       Ancora - dev'esserci una **ragione** per farlo. Se qualcosa ��
394181643Skmacy       ``unsigned long``, non c'�� alcun bisogno di avere:
395181643Skmacy
396181643Skmacy        typedef unsigned long myfalgs_t;
397181643Skmacy
398181643Skmacy      ma se ci sono chiare circostanze in cui potrebbe essere ``unsigned int``
399181643Skmacy      e in altre configurazioni ``unsigned long``, allora certamente typedef
400181643Skmacy      �� una buona scelta.
401181643Skmacy
402181643Skmacy (c) quando di rado create letteralmente dei **nuovi** tipi su cui effettuare
403181643Skmacy     verifiche.
404181643Skmacy
405181643Skmacy (d) circostanze eccezionali, in cui si definiscono nuovi tipi identici a
406181643Skmacy     quelli definiti dallo standard C99.
407181643Skmacy
408181643Skmacy     Nonostante ci voglia poco tempo per abituare occhi e cervello all'uso dei
409181643Skmacy     tipi standard come ``uint32_t``, alcune persone ne obiettano l'uso.
410181643Skmacy
411181643Skmacy     Perci��, i tipi specifici di Linux ``u8/u16/u32/u64`` e i loro equivalenti
412181643Skmacy     con segno, identici ai tipi standard, sono permessi- tuttavia, non sono
413181643Skmacy     obbligatori per il nuovo codice.
414181643Skmacy
415181643Skmacy (e) i tipi sicuri nella spazio utente.
416181643Skmacy
417181643Skmacy     In alcune strutture dati visibili dallo spazio utente non possiamo
418181643Skmacy     richiedere l'uso dei tipi C99 e nemmeno i vari ``u32`` descritti prima.
419181643Skmacy     Perci��, utilizziamo __u32 e tipi simili in tutte le strutture dati
420181643Skmacy     condivise con lo spazio utente.
421181643Skmacy
422181643SkmacyMagari ci sono altri casi validi, ma la regola di base dovrebbe essere di
423181643Skmacynon usare MAI MAI un typedef a meno che non rientri in una delle regole
424181643Skmacydescritte qui.
425181643Skmacy
426181643SkmacyIn generale, un puntatore, o una struttura a cui si ha accesso diretto in
427181643Skmacymodo ragionevole, non dovrebbero **mai** essere definite con un typedef.
428181643Skmacy
429181643Skmacy6) Funzioni
430181643Skmacy-----------
431181643Skmacy
432181643SkmacyLe funzioni dovrebbero essere brevi e carine, e fare una cosa sola.  Dovrebbero
433181643Skmacyoccupare uno o due schermi di testo (come tutti sappiamo, la dimensione
434181643Skmacydi uno schermo secondo ISO/ANSI �� di 80x24), e fare una cosa sola e bene.
435181643Skmacy
436181643SkmacyLa massima lunghezza di una funziona �� inversamente proporzionale alla sua
437181643Skmacycomplessit�� e al livello di indentazione di quella funzione.  Quindi, se avete
438181643Skmacyuna funzione che �� concettualmente semplice ma che �� implementata come un
439181643Skmacylunga (ma semplice) sequenza di caso-istruzione, dove avete molte piccole cose
440181643Skmacyper molti casi differenti, allora va bene avere funzioni pi�� lunghe.
441181643Skmacy
442181643SkmacyComunque, se avete una funzione complessa e sospettate che uno studente
443181643Skmacynon particolarmente dotato del primo anno delle scuole superiori potrebbe
444181643Skmacynon capire cosa faccia la funzione, allora dovreste attenervi strettamente ai
445181643Skmacylimiti.  Usate funzioni di supporto con nomi descrittivi (potete chiedere al
446181643Skmacycompilatore di renderle inline se credete che sia necessario per le
447181643Skmacyprestazioni, e probabilmente far�� un lavoro migliore di quanto avreste potuto
448181643Skmacyfare voi).
449181643Skmacy
450181643SkmacyUn'altra misura delle funzioni sono il numero di variabili locali.  Non
451181643Skmacydovrebbero eccedere le 5-10, oppure state sbagliando qualcosa.  Ripensate la
452181643Skmacyfunzione, e dividetela in pezzettini.  Generalmente, un cervello umano pu��
453181643Skmacyseguire facilmente circa 7 cose diverse, di pi�� lo confonderebbe.  Lo sai
454181643Skmacyd'essere brillante, ma magari vorresti riuscire a capire cos'avevi fatto due
455181643Skmacysettimane prima.
456181643Skmacy
457181643SkmacyNei file sorgenti, separate le funzioni con una riga vuota.  Se la funzione ��
458181643Skmacyesportata, la macro **EXPORT** per questa funzione deve seguire immediatamente
459181643Skmacyla riga della parentesi graffa di chiusura. Ad esempio:
460181643Skmacy
461181643Skmacy.. code-block:: c
462181643Skmacy
463181643Skmacy	int system_is_up(void)
464181643Skmacy	{
465181643Skmacy		return system_state == SYSTEM_RUNNING;
466181643Skmacy	}
467181643Skmacy	EXPORT_SYMBOL(system_is_up);
468181643Skmacy
469181643Skmacy6.1) Prototipi di funzione
470181643Skmacy**************************
471181643Skmacy
472181643SkmacyNei prototipi di funzione, includete i nomi dei parametri e i loro tipi.
473181643SkmacyNonostante questo non sia richiesto dal linguaggio C, in Linux viene preferito
474181643Skmacyperch�� �� un modo semplice per aggiungere informazioni importanti per il
475181643Skmacylettore.
476181643Skmacy
477181643SkmacyNon usate la parola chiave ``extern`` con le dichiarazioni di funzione perch��
478181643Skmacyrende le righe pi�� lunghe e non �� strettamente necessario.
479181643Skmacy
480181643SkmacyQuando scrivete i prototipi di funzione mantenete `l'ordine degli elementi <https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_.
481181643Skmacy
482181643SkmacyPrendiamo questa dichiarazione di funzione come esempio::
483181643Skmacy
484181643Skmacy __init void * __must_check action(enum magic value, size_t size, u8 count,
485181643Skmacy                                  char *fmt, ...) __printf(4, 5) __malloc;
486181643Skmacy
487181643SkmacyL'ordine suggerito per gli elementi di un prototipo di funzione �� il seguente:
488181643Skmacy
489181643Skmacy- classe d'archiviazione (in questo caso ``static __always_inline``. Da notare
490181643Skmacy  che ``__always_inline`` �� tecnicamente un attributo ma che viene trattato come
491181643Skmacy  ``inline``)
492181643Skmacy- attributi della classe di archiviazione (in questo caso ``__init``, in altre
493181643Skmacy  parole la sezione, ma anche cose tipo ``__cold``)
494181643Skmacy- il tipo di ritorno (in questo caso, ``void *``)
495181643Skmacy- attributi per il valore di ritorno (in questo caso, ``__must_check``)
496181643Skmacy- il nome della funzione (in questo caso, ``action``)
497181643Skmacy- i parametri della funzione(in questo caso,
498181643Skmacy  ``(enum magic value, size_t size, u8 count, char *fmt, ...)``,
499181643Skmacy  da notare che va messo anche il nome del parametro)
500181643Skmacy- attributi dei parametri (in questo caso, ``__printf(4, 5)``)
501181643Skmacy- attributi per il comportamento della funzione (in questo caso, ``__malloc_``)
502181643Skmacy
503181643SkmacyNotate che per la **definizione** di una funzione (il altre parole il corpo
504181643Skmacydella funzione), il compilatore non permette di usare gli attributi per i
505181643Skmacyparametri dopo i parametri. In questi casi, devono essere messi dopo gli
506181643Skmacyattributi della classe d'archiviazione (notate che la posizione di
507181643Skmacy``__printf(4,5)`` cambia rispetto alla **dichiarazione**)::
508181643Skmacy
509181643Skmacy static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value,
510181643Skmacy              size_t size, u8 count, char *fmt, ...) __malloc
511181643Skmacy {
512181643Skmacy         ...
513181643Skmacy }*)**``)**``)``)``*)``)``)``)``*``)``)``)*)
514181643Skmacy
515181643Skmacy7) Centralizzare il ritorno delle funzioni
516181643Skmacy------------------------------------------
517181643Skmacy
518181643SkmacySebbene sia deprecata da molte persone, l'istruzione goto �� impiegata di
519181643Skmacyfrequente dai compilatori sotto forma di salto incondizionato.
520181643Skmacy
521181643SkmacyL'istruzione goto diventa utile quando una funzione ha punti d'uscita multipli
522181643Skmacye vanno eseguite alcune procedure di pulizia in comune.  Se non �� necessario
523181643Skmacypulire alcunch��, allora ritornate direttamente.
524181643Skmacy
525181643SkmacyAssegnate un nome all'etichetta di modo che suggerisca cosa fa la goto o
526181643Skmacyperch�� esiste.  Un esempio di un buon nome potrebbe essere ``out_free_buffer:``
527181643Skmacyse la goto libera (free) un ``buffer``.  Evitate l'uso di nomi GW-BASIC come
528181643Skmacy``err1:`` ed ``err2:``, potreste doverli riordinare se aggiungete o rimuovete
529181643Skmacypunti d'uscita, e inoltre rende difficile verificarne la correttezza.
530181643Skmacy
531181643SkmacyI motivo per usare le goto sono:
532181643Skmacy
533181643Skmacy- i salti incondizionati sono pi�� facili da capire e seguire
534181643Skmacy- l'annidamento si riduce
535181643Skmacy- si evita di dimenticare, per errore, di aggiornare un singolo punto d'uscita
536181643Skmacy- aiuta il compilatore ad ottimizzare il codice ridondante ;)
537181643Skmacy
538181643Skmacy.. code-block:: c
539181643Skmacy
540181643Skmacy	int fun(int a)
541181643Skmacy	{
542181643Skmacy		int result = 0;
543181643Skmacy		char *buffer;
544181643Skmacy
545181643Skmacy		buffer = kmalloc(SIZE, GFP_KERNEL);
546181643Skmacy		if (!buffer)
547181643Skmacy			return -ENOMEM;
548181643Skmacy
549181643Skmacy		if (condition1) {
550181643Skmacy			while (loop1) {
551181643Skmacy				...
552181643Skmacy			}
553181643Skmacy			result = 1;
554181643Skmacy			goto out_free_buffer;
555181643Skmacy		}
556181643Skmacy		...
557181643Skmacy	out_free_buffer:
558181643Skmacy		kfree(buffer);
559181643Skmacy		return result;
560181643Skmacy	}
561181643Skmacy
562181643SkmacyUn baco abbastanza comune di cui bisogna prendere nota �� il ``one err bugs``
563181643Skmacyche assomiglia a questo:
564181643Skmacy
565181643Skmacy.. code-block:: c
566181643Skmacy
567181643Skmacy	err:
568181643Skmacy		kfree(foo->bar);
569181643Skmacy		kfree(foo);
570181643Skmacy		return ret;
571181643Skmacy
572181643SkmacyIl baco in questo codice �� che in alcuni punti d'uscita la variabile ``foo`` ��
573181643SkmacyNULL.  Normalmente si corregge questo baco dividendo la gestione dell'errore in
574181643Skmacydue parti ``err_free_bar:`` e ``err_free_foo:``:
575181643Skmacy
576181643Skmacy.. code-block:: c
577181643Skmacy
578181643Skmacy	err_free_bar:
579181643Skmacy		kfree(foo->bar);
580181643Skmacy	err_free_foo:
581181643Skmacy		kfree(foo);
582181643Skmacy		return ret;
583181643Skmacy
584181643SkmacyIdealmente, dovreste simulare condizioni d'errore per verificare i vostri
585181643Skmacypercorsi d'uscita.
586181643Skmacy
587181643Skmacy
588181643Skmacy8) Commenti
589181643Skmacy-----------
590181643Skmacy
591181643SkmacyI commenti sono una buona cosa, ma c'�� anche il rischio di esagerare.  MAI
592181643Skmacyspiegare COME funziona il vostro codice in un commento: �� molto meglio
593181643Skmacyscrivere il codice di modo che il suo funzionamento sia ovvio, inoltre
594181643Skmacyspiegare codice scritto male �� una perdita di tempo.
595181643Skmacy
596181643SkmacySolitamente, i commenti devono dire COSA fa il codice, e non COME lo fa.
597181643SkmacyInoltre, cercate di evitare i commenti nel corpo della funzione: se la
598181643Skmacyfunzione �� cos�� complessa che dovete commentarla a pezzi, allora dovreste
599181643Skmacytornare al punto 6 per un momento.  Potete mettere dei piccoli commenti per
600181643Skmacyannotare o avvisare il lettore circa un qualcosa di particolarmente arguto
601181643Skmacy(o brutto), ma cercate di non esagerare.  Invece, mettete i commenti in
602181643Skmacytesta alla funzione spiegando alle persone cosa fa, e possibilmente anche
603181643Skmacyil PERCH��.
604181643Skmacy
605181643SkmacyPer favore, quando commentate una funzione dell'API del kernel usate il
606181643Skmacyformato kernel-doc.  Per maggiori dettagli, leggete i file in
607181643Skmacy:ref::ref:`Documentation/translations/it_IT/doc-guide/ <it_doc_guide>` e in
608181643Skmacy``script/kernel-doc``.
609181643Skmacy
610181643SkmacyLo stile preferito per i commenti pi�� lunghi (multi-riga) ��:
611181643Skmacy
612181643Skmacy.. code-block:: c
613181643Skmacy
614181643Skmacy	/*
615181643Skmacy	 * This is the preferred style for multi-line
616181643Skmacy	 * comments in the Linux kernel source code.
617181643Skmacy	 * Please use it consistently.
618181643Skmacy	 *
619181643Skmacy	 * Description:  A column of asterisks on the left side,
620181643Skmacy	 * with beginning and ending almost-blank lines.
621181643Skmacy	 */
622181643Skmacy
623181643SkmacyPer i file in net/ e in drivers/net/ lo stile preferito per i commenti
624181643Skmacypi�� lunghi (multi-riga) �� leggermente diverso.
625181643Skmacy
626181643Skmacy.. code-block:: c
627181643Skmacy
628181643Skmacy	/* The preferred comment style for files in net/ and drivers/net
629181643Skmacy	 * looks like this.
630181643Skmacy	 *
631181643Skmacy	 * It is nearly the same as the generally preferred comment style,
632181643Skmacy	 * but there is no initial almost-blank line.
633181643Skmacy	 */
634181643Skmacy
635181643Skmacy�� anche importante commentare i dati, sia per i tipi base che per tipi
636181643Skmacyderivati.  A questo scopo, dichiarate un dato per riga (niente virgole
637181643Skmacyper una dichiarazione multipla).  Questo vi lascer�� spazio per un piccolo
638181643Skmacycommento per spiegarne l'uso.
639181643Skmacy
640181643Skmacy
641181643Skmacy9) Avete fatto un pasticcio
642181643Skmacy---------------------------
643181643Skmacy
644181643SkmacyVa bene, li facciamo tutti.  Probabilmente vi �� stato detto dal vostro
645181643Skmacyaiutante Unix di fiducia che ``GNU emacs`` formatta automaticamente il
646181643Skmacycodice C per conto vostro, e avete notato che s��, in effetti lo fa, ma che
647181643Skmacyi modi predefiniti non sono proprio allettanti (infatti, sono peggio che
648181643Skmacypremere tasti a caso - un numero infinito di scimmie che scrivono in
649181643SkmacyGNU emacs non faranno mai un buon programma).
650181643Skmacy
651181643SkmacyQuindi, potete sbarazzarvi di GNU emacs, o riconfigurarlo con valori pi��
652181643Skmacysensati.  Per fare quest'ultima cosa, potete appiccicare il codice che
653181643Skmacysegue nel vostro file .emacs:
654181643Skmacy
655181643Skmacy.. code-block:: none
656181643Skmacy
657181643Skmacy  (defun c-lineup-arglist-tabs-only (ignored)
658181643Skmacy    "Line up argument lists by tabs, not spaces"
659181643Skmacy    (let* ((anchor (c-langelem-pos c-syntactic-element))
660181643Skmacy           (column (c-langelem-2nd-pos c-syntactic-element))
661181643Skmacy           (offset (- (1+ column) anchor))
662181643Skmacy           (steps (floor offset c-basic-offset)))
663181643Skmacy      (* (max steps 1)
664181643Skmacy         c-basic-offset)))
665181643Skmacy
666181643Skmacy  (dir-locals-set-class-variables
667181643Skmacy   'linux-kernel
668181643Skmacy   '((c-mode . (
669181643Skmacy          (c-basic-offset . 8)
670181643Skmacy          (c-label-minimum-indentation . 0)
671181643Skmacy          (c-offsets-alist . (
672181643Skmacy                  (arglist-close         . c-lineup-arglist-tabs-only)
673181643Skmacy                  (arglist-cont-nonempty .
674181643Skmacy                      (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only))
675181643Skmacy                  (arglist-intro         . +)
676181643Skmacy                  (brace-list-intro      . +)
677181643Skmacy                  (c                     . c-lineup-C-comments)
678181643Skmacy                  (case-label            . 0)
679181643Skmacy                  (comment-intro         . c-lineup-comment)
680181643Skmacy                  (cpp-define-intro      . +)
681181643Skmacy                  (cpp-macro             . -1000)
682181643Skmacy                  (cpp-macro-cont        . +)
683181643Skmacy                  (defun-block-intro     . +)
684181643Skmacy                  (else-clause           . 0)
685181643Skmacy                  (func-decl-cont        . +)
686181643Skmacy                  (inclass               . +)
687181643Skmacy                  (inher-cont            . c-lineup-multi-inher)
688181643Skmacy                  (knr-argdecl-intro     . 0)
689181643Skmacy                  (label                 . -1000)
690181643Skmacy                  (statement             . 0)
691181643Skmacy                  (statement-block-intro . +)
692181643Skmacy                  (statement-case-intro  . +)
693181643Skmacy                  (statement-cont        . +)
694181643Skmacy                  (substatement          . +)
695181643Skmacy                  ))
696181643Skmacy          (indent-tabs-mode . t)
697181643Skmacy          (show-trailing-whitespace . t)
698181643Skmacy          ))))
699181643Skmacy
700181643Skmacy  (dir-locals-set-directory-class
701181643Skmacy   (expand-file-name "~/src/linux-trees")
702181643Skmacy   'linux-kernel)
703181643Skmacy
704181643SkmacyQuesto far�� funzionare meglio emacs con lo stile del kernel per i file che
705181643Skmacysi trovano nella cartella ``~/src/linux-trees``.
706181643Skmacy
707181643SkmacyMa anche se doveste fallire nell'ottenere una formattazione sensata in emacs
708181643Skmacynon tutto �� perduto: usate ``indent``.
709181643Skmacy
710181643SkmacyOra, ancora, GNU indent ha la stessa configurazione decerebrata di GNU emacs,
711181643Skmacyed �� per questo che dovete passargli alcune opzioni da riga di comando.
712181643SkmacyTuttavia, non �� cos�� terribile, perch�� perfino i creatori di GNU indent
713181643Skmacyriconoscono l'autorit�� di K&R (le persone del progetto GNU non sono cattive,
714181643Skmacysono solo mal indirizzate sull'argomento), quindi date ad indent le opzioni
715181643Skmacy``-kr -i8`` (che significa ``K&R, 8 caratteri di indentazione``), o utilizzate
716181643Skmacy``scripts/Lindent`` che indenter�� usando l'ultimo stile.
717181643Skmacy
718181643Skmacy``indent`` ha un sacco di opzioni, e specialmente quando si tratta di
719181643Skmacyriformattare i commenti dovreste dare un'occhiata alle pagine man.
720181643SkmacyMa ricordatevi: ``indent`` non �� un correttore per una cattiva programmazione.
721181643Skmacy
722181643SkmacyDa notare che potete utilizzare anche ``clang-format`` per aiutarvi con queste
723181643Skmacyregole, per riformattare rapidamente ad automaticamente alcune parti del
724181643Skmacyvostro codice, e per revisionare interi file al fine di identificare errori
725181643Skmacydi stile, refusi e possibilmente anche delle migliorie. �� anche utile per
726181643Skmacyordinare gli ``#include``, per allineare variabili/macro, per ridistribuire
727181643Skmacyil testo e altre cose simili.
728181643SkmacyPer maggiori dettagli, consultate il file
729181643Skmacy:ref:`Documentation/translations/it_IT/process/clang-format.rst <it_clangformat>`.
730181643Skmacy
731181643Skmacy
732181643Skmacy10) File di configurazione Kconfig
733181643Skmacy----------------------------------
734181643Skmacy
735181643SkmacyPer tutti i file di configurazione Kconfig* che si possono trovare nei
736181643Skmacysorgenti, l'indentazione �� un po' differente.  Le linee dopo un ``config``
737181643Skmacysono indentate con un tab, mentre il testo descrittivo �� indentato di
738181643Skmacyulteriori due spazi.  Esempio::
739181643Skmacy
740181643Skmacy  config AUDIT
741181643Skmacy	bool "Auditing support"
742181643Skmacy	depends on NET
743181643Skmacy	help
744181643Skmacy	  Enable auditing infrastructure that can be used with another
745181643Skmacy	  kernel subsystem, such as SELinux (which requires this for
746181643Skmacy	  logging of avc messages output).  Does not do system-call
747181643Skmacy	  auditing without CONFIG_AUDITSYSCALL.
748181643Skmacy
749181643SkmacyLe funzionalit�� davvero pericolose (per esempio il supporto alla scrittura
750181643Skmacyper certi filesystem) dovrebbero essere dichiarate chiaramente come tali
751181643Skmacynella stringa di titolo::
752181643Skmacy
753181643Skmacy  config ADFS_FS_RW
754181643Skmacy	bool "ADFS write support (DANGEROUS)"
755181643Skmacy	depends on ADFS_FS
756181643Skmacy	...
757181643Skmacy
758181643SkmacyPer la documentazione completa sui file di configurazione, consultate
759181643Skmacyil documento Documentation/kbuild/kconfig-language.rst
760181643Skmacy
761181643Skmacy
762181643Skmacy11) Strutture dati
763181643Skmacy------------------
764181643Skmacy
765181643SkmacyLe strutture dati che hanno una visibilit�� superiore al contesto del
766181643Skmacysingolo thread in cui vengono create e distrutte, dovrebbero sempre
767181643Skmacyavere un contatore di riferimenti.  Nel kernel non esiste un
768181643Skmacy*garbage collector* (e fuori dal kernel i *garbage collector* sono lenti
769181643Skmacye inefficienti), questo significa che **dovete** assolutamente avere un
770181643Skmacycontatore di riferimenti per ogni cosa che usate.
771181643Skmacy
772181643SkmacyAvere un contatore di riferimenti significa che potete evitare la
773181643Skmacysincronizzazione e permette a pi�� utenti di accedere alla struttura dati
774181643Skmacyin parallelo - e non doversi preoccupare di una struttura dati che
775181643Skmacyimprovvisamente sparisce dalla loro vista perch�� il loro processo dormiva
776181643Skmacyo stava facendo altro per un attimo.
777181643Skmacy
778181643SkmacyDa notare che la sincronizzazione **non** si sostituisce al conteggio dei
779181643Skmacyriferimenti.  La sincronizzazione ha lo scopo di mantenere le strutture
780181643Skmacydati coerenti, mentre il conteggio dei riferimenti �� una tecnica di gestione
781181643Skmacydella memoria.  Solitamente servono entrambe le cose, e non vanno confuse fra
782181643Skmacydi loro.
783181643Skmacy
784181643SkmacyQuando si hanno diverse classi di utenti, le strutture dati possono avere
785181643Skmacydue livelli di contatori di riferimenti.  Il contatore di classe conta
786181643Skmacyil numero dei suoi utenti, e il contatore globale viene decrementato una
787181643Skmacysola volta quando il contatore di classe va a zero.
788181643Skmacy
789181643SkmacyUn esempio di questo tipo di conteggio dei riferimenti multi-livello pu��
790181643Skmacyessere trovato nella gestore della memoria (``struct mm_sturct``: mm_user e
791181643Skmacymm_count), e nel codice dei filesystem (``struct super_block``: s_count e
792181643Skmacys_active).
793181643Skmacy
794181643SkmacyRicordatevi: se un altro thread pu�� trovare la vostra struttura dati, e non
795181643Skmacyavete un contatore di riferimenti per essa, quasi certamente avete un baco.
796181643Skmacy
797181643Skmacy12) Macro, enumerati e RTL
798181643Skmacy---------------------------
799181643Skmacy
800181643SkmacyI nomi delle macro che definiscono delle costanti e le etichette degli
801181643Skmacyenumerati sono scritte in maiuscolo.
802181643Skmacy
803181643Skmacy.. code-block:: c
804181643Skmacy
805181643Skmacy	#define CONSTANT 0x12345
806181643Skmacy
807181643SkmacyGli enumerati sono da preferire quando si definiscono molte costanti correlate.
808181643Skmacy
809181643SkmacyI nomi delle macro in MAIUSCOLO sono preferibili ma le macro che assomigliano
810181643Skmacya delle funzioni possono essere scritte in minuscolo.
811181643Skmacy
812181643SkmacyGeneralmente, le funzioni inline sono preferibili rispetto alle macro che
813181643Skmacysembrano funzioni.
814181643Skmacy
815181643SkmacyLe macro che contengono pi�� istruzioni dovrebbero essere sempre chiuse in un
816181643Skmacyblocco do - while:
817181643Skmacy
818181643Skmacy.. code-block:: c
819181643Skmacy
820181643Skmacy	#define macrofun(a, b, c)			\
821181643Skmacy		do {					\
822181643Skmacy			if (a == 5)			\
823181643Skmacy				do_this(b, c);		\
824181643Skmacy		} while (0)
825181643Skmacy
826181643SkmacyCose da evitare quando si usano le macro:
827181643Skmacy
828181643Skmacy1) le macro che hanno effetti sul flusso del codice:
829181643Skmacy
830181643Skmacy.. code-block:: c
831181643Skmacy
832181643Skmacy	#define FOO(x)					\
833181643Skmacy		do {					\
834181643Skmacy			if (blah(x) < 0)		\
835181643Skmacy				return -EBUGGERED;	\
836181643Skmacy		} while (0)
837181643Skmacy
838181643Skmacysono **proprio** una pessima idea.  Sembra una chiamata a funzione ma termina
839181643Skmacyla funzione chiamante; non cercate di rompere il decodificatore interno di
840181643Skmacychi legge il codice.
841181643Skmacy
842181643Skmacy2) le macro che dipendono dall'uso di una variabile locale con un nome magico:
843181643Skmacy
844181643Skmacy.. code-block:: c
845181643Skmacy
846181643Skmacy	#define FOO(val) bar(index, val)
847181643Skmacy
848181643Skmacypotrebbe sembrare una bella cosa, ma �� dannatamente confusionario quando uno
849181643Skmacylegge il codice e potrebbe romperlo con una cambiamento che sembra innocente.
850181643Skmacy
851181643Skmacy3) le macro con argomenti che sono utilizzati come l-values; questo potrebbe
852181643Skmacyritorcervisi contro se qualcuno, per esempio, trasforma FOO in una funzione
853181643Skmacyinline.
854181643Skmacy
855181643Skmacy4) dimenticatevi delle precedenze: le macro che definiscono espressioni devono
856181643Skmacyessere racchiuse fra parentesi. State attenti a problemi simili con le macro
857181643Skmacyparametrizzate.
858181643Skmacy
859181643Skmacy.. code-block:: c
860181643Skmacy
861181643Skmacy	#define CONSTANT 0x4000
862181643Skmacy	#define CONSTEXP (CONSTANT | 3)
863181643Skmacy
864181643Skmacy5) collisione nello spazio dei nomi quando si definisce una variabile locale in
865181643Skmacyuna macro che sembra una funzione:
866181643Skmacy
867181643Skmacy.. code-block:: c
868181643Skmacy
869181643Skmacy	#define FOO(x)				\
870181643Skmacy	({					\
871181643Skmacy		typeof(x) ret;			\
872181643Skmacy		ret = calc_ret(x);		\
873181643Skmacy		(ret);				\
874181643Skmacy	})
875181643Skmacy
876181643Skmacyret �� un nome comune per una variabile locale - __foo_ret difficilmente
877181643Skmacyandr�� in conflitto con una variabile gi�� esistente.
878181643Skmacy
879181643SkmacyIl manuale di cpp si occupa esaustivamente delle macro. Il manuale di sviluppo
880181643Skmacydi gcc copre anche l'RTL che viene usato frequentemente nel kernel per il
881181643Skmacylinguaggio assembler.
882181643Skmacy
883181643Skmacy13) Visualizzare i messaggi del kernel
884181643Skmacy--------------------------------------
885181643Skmacy
886181643SkmacyAgli sviluppatori del kernel piace essere visti come dotti. Tenete un occhio
887181643Skmacydi riguardo per l'ortografia e farete una belle figura. In inglese, evitate
888181643Skmacyl'uso incorretto di abbreviazioni come ``dont``: usate ``do not`` oppure
889181643Skmacy``don't``.  Scrivete messaggi concisi, chiari, e inequivocabili.
890181643Skmacy
891181643SkmacyI messaggi del kernel non devono terminare con un punto fermo.
892181643Skmacy
893181643SkmacyScrivere i numeri fra parentesi (%d) non migliora alcunch�� e per questo
894181643Skmacydovrebbero essere evitati.
895181643Skmacy
896181643SkmacyCi sono alcune macro per la diagnostica in <linux/dev_printk.h> che dovreste
897181643Skmacyusare per assicurarvi che i messaggi vengano associati correttamente ai
898181643Skmacydispositivi e ai driver, e che siano etichettati correttamente:  dev_err(),
899181643Skmacydev_warn(), dev_info(), e cos�� via.  Per messaggi che non sono associati ad
900181643Skmacyalcun dispositivo, <linux/printk.h> definisce pr_info(), pr_warn(), pr_err(),
901181643Skmacyeccetera.
902181643Skmacy
903181643SkmacyTirar fuori un buon messaggio di debug pu�� essere una vera sfida; e quando
904181643Skmacyl'avete pu�� essere d'enorme aiuto per risolvere problemi da remoto.
905181643SkmacyTuttavia, i messaggi di debug sono gestiti differentemente rispetto agli
906181643Skmacyaltri.  Le funzioni pr_XXX() stampano incondizionatamente ma pr_debug() no;
907181643Skmacyessa non viene compilata nella configurazione predefinita, a meno che
908181643SkmacyDEBUG o CONFIG_DYNAMIC_DEBUG non vengono impostati.  Questo vale anche per
909181643Skmacydev_dbg() e in aggiunta VERBOSE_DEBUG per aggiungere i messaggi dev_vdbg().
910181643Skmacy
911181643SkmacyMolti sottosistemi hanno delle opzioni di debug in Kconfig che aggiungono
912181643Skmacy-DDEBUG nei corrispettivi Makefile, e in altri casi aggiungono #define DEBUG
913181643Skmacyin specifici file.  Infine, quando un messaggio di debug dev'essere stampato
914181643Skmacyincondizionatamente, per esempio perch�� siete gi�� in una sezione di debug
915181643Skmacyracchiusa in #ifdef, potete usare printk(KERN_DEBUG ...).
916181643Skmacy
917181643Skmacy14) Assegnare memoria
918181643Skmacy---------------------
919181643Skmacy
920181643SkmacyIl kernel fornisce i seguenti assegnatori ad uso generico:
921181643Skmacykmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), e vzalloc().
922181643SkmacyPer maggiori informazioni, consultate la documentazione dell'API:
923181643Skmacy:ref:`Documentation/translations/it_IT/core-api/memory-allocation.rst <it_memory_allocation>`
924181643Skmacy
925181643SkmacyIl modo preferito per passare la dimensione di una struttura �� il seguente:
926181643Skmacy
927181643Skmacy.. code-block:: c
928181643Skmacy
929181643Skmacy	p = kmalloc(sizeof(*p), ...);
930181643Skmacy
931181643SkmacyLa forma alternativa, dove il nome della struttura viene scritto interamente,
932181643Skmacypeggiora la leggibilit�� e introduce possibili bachi quando il tipo di
933181643Skmacypuntatore cambia tipo ma il corrispondente sizeof non viene aggiornato.
934181643Skmacy
935181643SkmacyIl valore di ritorno �� un puntatore void, effettuare un cast su di esso ��
936181643Skmacyridondante. La conversione fra un puntatore void e un qualsiasi altro tipo
937181643Skmacydi puntatore �� garantito dal linguaggio di programmazione C.
938181643Skmacy
939181643SkmacyIl modo preferito per assegnare un vettore �� il seguente:
940181643Skmacy
941181643Skmacy.. code-block:: c
942181643Skmacy
943181643Skmacy	p = kmalloc_array(n, sizeof(...), ...);
944181643Skmacy
945181643SkmacyIl modo preferito per assegnare un vettore a zero �� il seguente:
946181643Skmacy
947181643Skmacy.. code-block:: c
948181643Skmacy
949181643Skmacy	p = kcalloc(n, sizeof(...), ...);
950181643Skmacy
951181643SkmacyEntrambe verificano la condizione di overflow per la dimensione
952181643Skmacyd'assegnamento n * sizeof(...), se accade ritorneranno NULL.
953181643Skmacy
954181643SkmacyQuesti allocatori generici producono uno *stack dump* in caso di fallimento
955181643Skmacya meno che non venga esplicitamente specificato __GFP_NOWARN. Quindi, nella
956181643Skmacymaggior parte dei casi, �� inutile stampare messaggi aggiuntivi quando uno di
957181643Skmacyquesti allocatori ritornano un puntatore NULL.
958181643Skmacy
959181643Skmacy15) Il morbo inline
960181643Skmacy-------------------
961181643Skmacy
962181643SkmacySembra che ci sia la percezione errata che gcc abbia una qualche magica
963181643Skmacyopzione "rendimi pi�� veloce" chiamata ``inline``. In alcuni casi l'uso di
964181643Skmacyinline �� appropriato (per esempio in sostituzione delle macro, vedi
965181643Skmacycapitolo 12), ma molto spesso non lo ��. L'uso abbondante della parola chiave
966181643Skmacyinline porta ad avere un kernel pi�� grande, che si traduce in un sistema nel
967181643Skmacysuo complesso pi�� lento per via di una cache per le istruzioni della CPU pi��
968181643Skmacygrande e poi semplicemente perch�� ci sar�� meno spazio disponibile per una
969181643Skmacypagina di cache. Pensateci un attimo; una fallimento nella cache causa una
970181643Skmacyricerca su disco che pu�� tranquillamente richiedere 5 millisecondi. Ci sono
971181643SkmacyTANTI cicli di CPU che potrebbero essere usati in questi 5 millisecondi.
972181643Skmacy
973181643SkmacySpesso le persone dicono che aggiungere inline a delle funzioni dichiarate
974181643Skmacystatic e utilizzare una sola volta �� sempre una scelta vincente perch�� non
975181643Skmacyci sono altri compromessi. Questo �� tecnicamente vero ma gcc �� in grado di
976181643Skmacytrasformare automaticamente queste funzioni in inline; i problemi di
977181643Skmacymanutenzione del codice per rimuovere gli inline quando compare un secondo
978181643Skmacyutente surclassano il potenziale vantaggio nel suggerire a gcc di fare una
979181643Skmacycosa che avrebbe fatto comunque.
980181643Skmacy
981181643Skmacy16) Nomi e valori di ritorno delle funzioni
982181643Skmacy-------------------------------------------
983181643Skmacy
984181643SkmacyLe funzioni possono ritornare diversi tipi di valori, e uno dei pi�� comuni
985181643Skmacy�� quel valore che indica se una funzione ha completato con successo o meno.
986181643SkmacyQuesto valore pu�� essere rappresentato come un codice di errore intero
987181643Skmacy(-Exxx = fallimento, 0 = successo) oppure un booleano di successo
988181643Skmacy(0 = fallimento, non-zero = successo).
989181643Skmacy
990181643SkmacyMischiare questi due tipi di rappresentazioni �� un terreno fertile per
991181643Skmacyi bachi pi�� insidiosi.  Se il linguaggio C includesse una forte distinzione
992181643Skmacyfra gli interi e i booleani, allora il compilatore potrebbe trovare questi
993181643Skmacyerrori per conto nostro ... ma questo non c'��.  Per evitare di imbattersi
994181643Skmacyin questo tipo di baco, seguite sempre la seguente convenzione::
995181643Skmacy
996181643Skmacy	Se il nome di una funzione �� un'azione o un comando imperativo,
997181643Skmacy	essa dovrebbe ritornare un codice di errore intero.  Se il nome
998181643Skmacy	�� un predicato, la funzione dovrebbe ritornare un booleano di
999181643Skmacy	"successo"
1000181643Skmacy
1001181643SkmacyPer esempio, ``add work`` �� un comando, e la funzione add_work() ritorna 0
1002181643Skmacyin caso di successo o -EBUSY in caso di fallimento.  Allo stesso modo,
1003181643Skmacy``PCI device present`` �� un predicato, e la funzione pci_dev_present() ritorna
1004181643Skmacy1 se trova il dispositivo corrispondente con successo, altrimenti 0.
1005181643Skmacy
1006181643SkmacyTutte le funzioni esportate (EXPORT) devono rispettare questa convenzione, e
1007181643Skmacycos�� dovrebbero anche tutte le funzioni pubbliche.  Le funzioni private
1008181643Skmacy(static) possono non seguire questa convenzione, ma �� comunque raccomandato
1009181643Skmacyche lo facciano.
1010181643Skmacy
1011181643SkmacyLe funzioni il cui valore di ritorno �� il risultato di una computazione,
1012181643Skmacypiuttosto che l'indicazione sul successo di tale computazione, non sono
1013181643Skmacysoggette a questa regola.  Solitamente si indicano gli errori ritornando un
1014181643Skmacyqualche valore fuori dai limiti.  Un tipico esempio �� quello delle funzioni
1015181643Skmacyche ritornano un puntatore; queste utilizzano NULL o ERR_PTR come meccanismo
1016181643Skmacydi notifica degli errori.
1017181643Skmacy
1018181643Skmacy17) L'uso di bool
1019181643Skmacy-----------------
1020181643Skmacy
1021181643SkmacyNel kernel Linux il tipo bool deriva dal tipo _Bool dello standard C99.
1022181643SkmacyUn valore bool pu�� assumere solo i valori 0 o 1, e implicitamente o
1023181643Skmacyesplicitamente la conversione a bool converte i valori in vero (*true*) o
1024181643Skmacyfalso (*false*).  Quando si usa un tipo bool il costrutto !! non sar�� pi��
1025181643Skmacynecessario, e questo va ad eliminare una certa serie di bachi.
1026181643Skmacy
1027181643SkmacyQuando si usano i valori booleani, dovreste utilizzare le definizioni di true
1028181643Skmacye false al posto dei valori 1 e 0.
1029181643Skmacy
1030181643SkmacyPer il valore di ritorno delle funzioni e per le variabili sullo stack, l'uso
1031181643Skmacydel tipo bool �� sempre appropriato.  L'uso di bool viene incoraggiato per
1032181643Skmacymigliorare la leggibilit�� e spesso �� molto meglio di 'int' nella gestione di
1033181643Skmacyvalori booleani.
1034181643Skmacy
1035181643SkmacyNon usate bool se per voi sono importanti l'ordine delle righe di cache o
1036181643Skmacyla loro dimensione; la dimensione e l'allineamento cambia a seconda
1037181643Skmacydell'architettura per la quale �� stato compilato.  Le strutture che sono state
1038181643Skmacyottimizzate per l'allineamento o la dimensione non dovrebbero usare bool.
1039181643Skmacy
1040181643SkmacySe una struttura ha molti valori true/false, considerate l'idea di raggrupparli
1041181643Skmacyin un intero usando campi da 1 bit, oppure usate un tipo dalla larghezza fissa,
1042181643Skmacycome u8.
1043181643Skmacy
1044181643SkmacyCome per gli argomenti delle funzioni, molti valori true/false possono essere
1045181643Skmacyraggruppati in un singolo argomento a bit denominato 'flags'; spesso 'flags' ��
1046181643Skmacyun'alternativa molto pi�� leggibile se si hanno valori costanti per true/false.
1047181643Skmacy
1048181643SkmacyDetto ci��, un uso parsimonioso di bool nelle strutture dati e negli argomenti
1049181643Skmacypu�� migliorare la leggibilit��.
1050181643Skmacy
1051181643Skmacy18) Non reinventate le macro del kernel
1052181643Skmacy---------------------------------------
1053181643Skmacy
1054181643SkmacyIl file di intestazione include/linux/kernel.h contiene un certo numero
1055181643Skmacydi macro che dovreste usare piuttosto che implementarne una qualche variante.
1056181643SkmacyPer esempio, se dovete calcolare la lunghezza di un vettore, sfruttate la
1057181643Skmacymacro:
1058181643Skmacy
1059181643Skmacy.. code-block:: c
1060181643Skmacy
1061181643Skmacy	#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
1062181643Skmacy
1063181643SkmacyAnalogamente, se dovete calcolare la dimensione di un qualche campo di una
1064181643Skmacystruttura, usate
1065181643Skmacy
1066181643Skmacy.. code-block:: c
1067181643Skmacy
1068181643Skmacy	#define sizeof_field(t, f) (sizeof(((t*)0)->f))
1069181643Skmacy
1070181643SkmacyCi sono anche le macro min() e max() che, se vi serve, effettuano un controllo
1071181643Skmacyrigido sui tipi.  Sentitevi liberi di leggere attentamente questo file
1072181643Skmacyd'intestazione per scoprire cos'altro �� stato definito che non dovreste
1073181643Skmacyreinventare nel vostro codice.
1074181643Skmacy
1075181643Skmacy19) Linee di configurazione degli editor e altre schifezze
1076181643Skmacy-----------------------------------------------------------
1077181643Skmacy
1078181643SkmacyAlcuni editor possono interpretare dei parametri di configurazione integrati
1079181643Skmacynei file sorgenti e indicati con dai marcatori speciali.  Per esempio, emacs
1080181643Skmacyinterpreta le linee marcate nel seguente modo:
1081181643Skmacy
1082181643Skmacy.. code-block:: c
1083181643Skmacy
1084181643Skmacy	-*- mode: c -*-
1085181643Skmacy
1086181643SkmacyO come queste:
1087181643Skmacy
1088181643Skmacy.. code-block:: c
1089181643Skmacy
1090181643Skmacy	/*
1091181643Skmacy	Local Variables:
1092181643Skmacy	compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"
1093181643Skmacy	End:
1094181643Skmacy	*/
1095181643Skmacy
1096181643SkmacyVim interpreta i marcatori come questi:
1097181643Skmacy
1098181643Skmacy.. code-block:: c
1099181643Skmacy
1100181643Skmacy	/* vim:set sw=8 noet */
1101181643Skmacy
1102181643SkmacyNon includete nessuna di queste cose nei file sorgenti.  Le persone hanno le
1103181643Skmacyproprie configurazioni personali per l'editor, e i vostri sorgenti non
1104181643Skmacydovrebbero sovrascrivergliele.  Questo vale anche per i marcatori
1105181643Skmacyd'indentazione e di modalit�� d'uso.  Le persone potrebbero aver configurato una
1106181643Skmacymodalit�� su misura, oppure potrebbero avere qualche altra magia per far
1107181643Skmacyfunzionare bene l'indentazione.
1108181643Skmacy
1109181643Skmacy20) Inline assembly
1110181643Skmacy-------------------
1111181643Skmacy
1112181643SkmacyNel codice specifico per un'architettura, potreste aver bisogno di codice
1113181643Skmacy*inline assembly* per interfacciarvi col processore o con una funzionalit��
1114181643Skmacyspecifica della piattaforma.  Non esitate a farlo quando �� necessario.
1115181643SkmacyComunque, non usatele gratuitamente quando il C pu�� fare la stessa cosa.
1116181643SkmacyPotete e dovreste punzecchiare l'hardware in C quando �� possibile.
1117181643Skmacy
1118181643SkmacyConsiderate la scrittura di una semplice funzione che racchiude pezzi comuni
1119181643Skmacydi codice assembler piuttosto che continuare a riscrivere delle piccole
1120181643Skmacyvarianti.  Ricordatevi che l' *inline assembly* pu�� utilizzare i parametri C.
1121181643Skmacy
1122181643SkmacyIl codice assembler pi�� corposo e non banale dovrebbe andare nei file .S,
1123181643Skmacycoi rispettivi prototipi C definiti nei file d'intestazione.  I prototipi C
1124181643Skmacyper le funzioni assembler dovrebbero usare ``asmlinkage``.
1125181643Skmacy
1126181643SkmacyPotreste aver bisogno di marcare il vostro codice asm come volatile al fine
1127181643Skmacyd'evitare che GCC lo rimuova quando pensa che non ci siano effetti collaterali.
1128181643SkmacyNon c'�� sempre bisogno di farlo, e farlo quando non serve limita le
1129181643Skmacyottimizzazioni.
1130181643Skmacy
1131181643SkmacyQuando scrivete una singola espressione *inline assembly* contenente pi��
1132181643Skmacyistruzioni, mettete ognuna di queste istruzioni in una stringa e riga diversa;
1133181643Skmacyad eccezione dell'ultima stringa/istruzione, ognuna deve terminare con ``\n\t``
1134181643Skmacyal fine di allineare correttamente l'assembler che verr�� generato:
1135181643Skmacy
1136181643Skmacy.. code-block:: c
1137181643Skmacy
1138181643Skmacy	asm ("magic %reg1, #42\n\t"
1139181643Skmacy	     "more_magic %reg2, %reg3"
1140181643Skmacy	     : /* outputs */ : /* inputs */ : /* clobbers */);
1141181643Skmacy
1142181643Skmacy21) Compilazione sotto condizione
1143181643Skmacy---------------------------------
1144181643Skmacy
1145181643SkmacyOvunque sia possibile, non usate le direttive condizionali del preprocessore
1146181643Skmacy(#if, #ifdef) nei file .c; farlo rende il codice difficile da leggere e da
1147181643Skmacyseguire.  Invece, usate queste direttive nei file d'intestazione per definire
1148181643Skmacyle funzioni usate nei file .c, fornendo i relativi stub nel caso #else,
1149181643Skmacye quindi chiamate queste funzioni senza condizioni di preprocessore.  Il
1150181643Skmacycompilatore non produrr�� alcun codice per le funzioni stub, produrr�� gli
1151181643Skmacystessi risultati, e la logica rimarr�� semplice da seguire.
1152181643Skmacy
1153181643Skmacy�� preferibile non compilare intere funzioni piuttosto che porzioni d'esse o
1154181643Skmacyporzioni d'espressioni.  Piuttosto che mettere una ifdef in un'espressione,
1155181643Skmacyfattorizzate parte dell'espressione, o interamente, in funzioni e applicate
1156181643Skmacyla direttiva condizionale su di esse.
1157181643Skmacy
1158181643SkmacySe avete una variabile o funzione che potrebbe non essere usata in alcune
1159181643Skmacyconfigurazioni, e quindi il compilatore potrebbe avvisarvi circa la definizione
1160181643Skmacyinutilizzata, marcate questa definizione come __maybe_unused piuttosto che
1161181643Skmacyracchiuderla in una direttiva condizionale del preprocessore.  (Comunque,
1162181643Skmacyse una variabile o funzione �� *sempre* inutilizzata, rimuovetela).
1163181643Skmacy
1164181643SkmacyNel codice, dov'�� possibile, usate la macro IS_ENABLED per convertire i
1165181643Skmacysimboli Kconfig in espressioni booleane C, e quindi usatela nelle classiche
1166181643Skmacycondizioni C:
1167181643Skmacy
1168181643Skmacy.. code-block:: c
1169181643Skmacy
1170181643Skmacy	if (IS_ENABLED(CONFIG_SOMETHING)) {
1171181643Skmacy		...
1172181643Skmacy	}
1173181643Skmacy
1174181643SkmacyIl compilatore valuter�� la condizione come costante (constant-fold), e quindi
1175181643Skmacyincluder�� o escluder�� il blocco di codice come se fosse in un #ifdef, quindi
1176181643Skmacynon ne aumenter�� il tempo di esecuzione.  Tuttavia, questo permette al
1177181643Skmacycompilatore C di vedere il codice nel blocco condizionale e verificarne la
1178181643Skmacycorrettezza (sintassi, tipi, riferimenti ai simboli, eccetera).  Quindi
1179181643Skmacydovete comunque utilizzare #ifdef se il codice nel blocco condizionale esiste
1180181643Skmacysolo quando la condizione �� soddisfatta.
1181181643Skmacy
1182181643SkmacyAlla fine di un blocco corposo di #if o #ifdef (pi�� di alcune linee),
1183181643Skmacymettete un commento sulla stessa riga di #endif, annotando la condizione
1184181643Skmacyche termina.  Per esempio:
1185181643Skmacy
1186181643Skmacy.. code-block:: c
1187181643Skmacy
1188181643Skmacy	#ifdef CONFIG_SOMETHING
1189181643Skmacy	...
1190181643Skmacy	#endif /* CONFIG_SOMETHING */
1191181643Skmacy
1192181643SkmacyAppendice I) riferimenti
1193181643Skmacy------------------------
1194181643Skmacy
1195181643SkmacyThe C Programming Language, Second Edition
1196181643Skmacyby Brian W. Kernighan and Dennis M. Ritchie.
1197181643SkmacyPrentice Hall, Inc., 1988.
1198181643SkmacyISBN 0-13-110362-8 (paperback), 0-13-110370-9 (hardback).
1199181643Skmacy
1200181643SkmacyThe Practice of Programming
1201181643Skmacyby Brian W. Kernighan and Rob Pike.
1202181643SkmacyAddison-Wesley, Inc., 1999.
1203181643SkmacyISBN 0-201-61586-X.
1204181643Skmacy
1205181643SkmacyManuali GNU - nei casi in cui sono compatibili con K&R e questo documento -
1206181643Skmacyper indent, cpp, gcc e i suoi dettagli interni, tutto disponibile qui
1207181643Skmacyhttps://www.gnu.org/manual/
1208181643Skmacy
1209181643SkmacyWG14 �� il gruppo internazionale di standardizzazione per il linguaggio C,
1210181643SkmacyURL: https://www.open-std.org/JTC1/SC22/WG14/
1211181643Skmacy
1212181643SkmacyKernel CodingStyle, by greg@kroah.com at OLS 2002:
1213181643Skmacyhttp://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/
1214181643Skmacy