← Documents Documentation/translations/it_IT/process/coding-style.rst GitHub 원문 ↗

Linux 6.18.37 · Translations

Linux kernel coding style

들여쓰기부터 이름·typedef·함수·주석·macro·메모리·inline assembly·조건부 compile까지 kernel C style을 설명합니다.

Source pathDocumentation/translations/it_IT/process/coding-style.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

coding-style.rst:1-1230

Linux kernel C source가 공유하는 들여쓰기, 줄 길이, brace와 공백, naming, typedef, 함수와 comment 규칙을 실제 좋은·나쁜 예제로 설명합니다.

Kconfig, data structure lifetime, macro·enum, printk, allocation, inline, bool, 기존 helper 재사용, editor modeline, inline assembly와 conditional compilation까지 유지보수성과 review를 위한 규칙을 다룹니다.

같은 v6.18.37 영어 정식 문서에는 이 이탈리아어판에 없는 ‘커널을 중단하지 않기’ 절이 추가되어 있습니다. 로컬 이탈리아어 원문 우선 원칙에 따라 해당 절은 한국어 전문에 자동 삽입하지 않고 버전 차이로만 기록합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. include:: ../disclaimer-ita.rst
2
3 :Original: :ref:`Documentation/process/coding-style.rst <codingstyle>`
4 :Translator: Federico Vaga <[email protected]>
5
6 .. _it_codingstyle:
7
8 Stile del codice per il kernel Linux
9 ====================================
10
11 Questo è un breve documento che descrive lo stile di codice preferito per
12 il kernel Linux. Lo stile di codifica è molto personale e non voglio
13 **forzare** nessuno ad accettare il mio, ma questo stile è quello che
14 dev'essere usato per qualsiasi cosa che io sia in grado di mantenere, e l'ho
15 preferito anche per molte altre cose. Per favore, almeno tenete in
16 considerazione le osservazioni espresse qui.
17
18 La prima cosa che suggerisco è quella di stamparsi una copia degli standard
19 di codifica GNU e di NON leggerla. Bruciatela, è un grande gesto simbolico.
20
21 Comunque, ecco i punti:
22
23 1) Indentazione
24 ---------------
25
26 La tabulazione (tab) è di 8 caratteri e così anche le indentazioni. Ci sono
27 alcuni movimenti di eretici che vorrebbero l'indentazione a 4 (o perfino 2!)
28 caratteri di profondità, che è simile al tentativo di definire il valore del
29 pi-greco a 3.
30
31 Motivazione: l'idea dell'indentazione è di definire chiaramente dove un blocco
32 di controllo inizia e finisce. Specialmente quando siete rimasti a guardare lo
33 schermo per 20 ore a file, troverete molto più facile capire i livelli di
34 indentazione se questi sono larghi.
35
36 Ora, alcuni rivendicano che un'indentazione da 8 caratteri sposta il codice
37 troppo a destra e che quindi rende difficile la lettura su schermi a 80
38 caratteri. La risposta a questa affermazione è che se vi servono più di 3
39 livelli di indentazione, siete comunque fregati e dovreste correggere il vostro
40 programma.
41
42 In breve, l'indentazione ad 8 caratteri rende più facile la lettura, e in
43 aggiunta vi avvisa quando state annidando troppo le vostre funzioni.
44 Tenete ben a mente questo avviso.
45
46 Al fine di facilitare l'indentazione del costrutto switch, si preferisce
47 allineare sulla stessa colonna la parola chiave ``switch`` e i suoi
48 subordinati ``case``. In questo modo si evita una doppia indentazione per
49 i ``case``. Un esempio.:
50
51 .. code-block:: c
52
53 switch (suffix) {
54 case 'G':
55 case 'g':
56 mem <<= 30;
57 break;
58 case 'M':
59 case 'm':
60 mem <<= 20;
61 break;
62 case 'K':
63 case 'k':
64 mem <<= 10;
65 fallthrough;
66 default:
67 break;
68 }
69
70 A meno che non vogliate nascondere qualcosa, non mettete più istruzioni sulla
71 stessa riga:
72
73 .. code-block:: c
74
75 if (condition) do_this;
76 do_something_everytime;
77
78 Non usate le virgole per evitare le parentesi:
79
80 .. code-block:: c
81
82 if (condition)
83 do_this(), do_that();
84
85 Invece, usate sempre le parentesi per racchiudere più istruzioni.
86
87 .. code-block:: c
88
89 if (condition) {
90 do_this();
91 do_that();
92 }
93
94 Non mettete nemmeno più assegnamenti sulla stessa riga. Lo stile del kernel
95 è ultrasemplice. Evitate espressioni intricate.
96
97
98 Al di fuori dei commenti, della documentazione ed escludendo i Kconfig, gli
99 spazi non vengono mai usati per l'indentazione, e l'esempio qui sopra è
100 volutamente errato.
101
102 Procuratevi un buon editor di testo e non lasciate spazi bianchi alla fine
103 delle righe.
104
105
106 2) Spezzare righe lunghe e stringhe
107 -----------------------------------
108
109 Lo stile del codice riguarda la leggibilità e la manutenibilità utilizzando
110 strumenti comuni.
111
112 Come limite di riga si preferiscono le 80 colonne.
113
114 Espressioni più lunghe di 80 colonne dovrebbero essere spezzettate in
115 pezzi più piccoli, a meno che eccedere le 80 colonne non aiuti ad
116 aumentare la leggibilità senza nascondere informazioni.
117
118 I nuovi pezzi derivati sono sostanzialmente più corti degli originali
119 e vengono posizionati più a destra. Uno stile molto comune è quello di
120 allineare i nuovi pezzi alla parentesi aperta di una funzione.
121
122 Lo stesso si applica, nei file d'intestazione, alle funzioni con una
123 lista di argomenti molto lunga.
124
125 Tuttavia, non spezzettate mai le stringhe visibili agli utenti come i
126 messaggi di printk, questo perché inibireste la possibilità
127 d'utilizzare grep per cercarle.
128
129 3) Posizionamento di parentesi graffe e spazi
130 ---------------------------------------------
131
132 Un altro problema che s'affronta sempre quando si parla di stile in C è
133 il posizionamento delle parentesi graffe. Al contrario della dimensione
134 dell'indentazione, non ci sono motivi tecnici sulla base dei quali scegliere
135 una strategia di posizionamento o un'altra; ma il modo qui preferito,
136 come mostratoci dai profeti Kernighan e Ritchie, è quello di
137 posizionare la parentesi graffa di apertura per ultima sulla riga, e quella
138 di chiusura per prima su una nuova riga, così:
139
140 .. code-block:: c
141
142 if (x is true) {
143 we do y
144 }
145
146 Questo è valido per tutte le espressioni che non siano funzioni (if, switch,
147 for, while, do). Per esempio:
148
149 .. code-block:: c
150
151 switch (action) {
152 case KOBJ_ADD:
153 return "add";
154 case KOBJ_REMOVE:
155 return "remove";
156 case KOBJ_CHANGE:
157 return "change";
158 default:
159 return NULL;
160 }
161
162 Tuttavia, c'è il caso speciale, le funzioni: queste hanno la parentesi graffa
163 di apertura all'inizio della riga successiva, quindi:
164
165 .. code-block:: c
166
167 int function(int x)
168 {
169 body of function
170 }
171
172 Eretici da tutto il mondo affermano che questa incoerenza è ...
173 insomma ... incoerente, ma tutte le persone ragionevoli sanno che (a)
174 K&R hanno **ragione** e (b) K&R hanno ragione. A parte questo, le funzioni
175 sono comunque speciali (non potete annidarle in C).
176
177 Notate che la graffa di chiusura è da sola su una riga propria, ad
178 **eccezione** di quei casi dove è seguita dalla continuazione della stessa
179 espressione, in pratica ``while`` nell'espressione do-while, oppure ``else``
180 nell'espressione if-else, come questo:
181
182 .. code-block:: c
183
184 do {
185 body of do-loop
186 } while (condition);
187
188 e
189
190 .. code-block:: c
191
192 if (x == y) {
193 ..
194 } else if (x > y) {
195 ...
196 } else {
197 ....
198 }
199
200 Motivazione: K&R.
201
202 Inoltre, notate che questo posizionamento delle graffe minimizza il numero
203 di righe vuote senza perdere di leggibilità. In questo modo, dato che le
204 righe sul vostro schermo non sono una risorsa illimitata (pensate ad uno
205 terminale con 25 righe), avrete delle righe vuote da riempire con dei
206 commenti.
207
208 Non usate inutilmente le graffe dove una singola espressione è sufficiente.
209
210 .. code-block:: c
211
212 if (condition)
213 action();
214
215 e
216
217 .. code-block:: c
218
219 if (condition)
220 do_this();
221 else
222 do_that();
223
224 Questo non vale nel caso in cui solo un ramo dell'espressione if-else
225 contiene una sola espressione; in quest'ultimo caso usate le graffe per
226 entrambe i rami:
227
228 .. code-block:: c
229
230 if (condition) {
231 do_this();
232 do_that();
233 } else {
234 otherwise();
235 }
236
237 Inoltre, usate le graffe se un ciclo contiene più di una semplice istruzione:
238
239 .. code-block:: c
240
241 while (condition) {
242 if (test)
243 do_something();
244 }
245
246 3.1) Spazi
247 **********
248
249 Lo stile del kernel Linux per quanto riguarda gli spazi, dipende
250 (principalmente) dalle funzioni e dalle parole chiave. Usate una spazio dopo
251 (quasi tutte) le parole chiave. L'eccezioni più evidenti sono sizeof, typeof,
252 alignof, e __attribute__, il cui aspetto è molto simile a quello delle
253 funzioni (e in Linux, solitamente, sono usate con le parentesi, anche se il
254 linguaggio non lo richiede; come ``sizeof info`` dopo aver dichiarato
255 ``struct fileinfo info``).
256
257 Quindi utilizzate uno spazio dopo le seguenti parole chiave::
258
259 if, switch, case, for, do, while
260
261 ma non con sizeof, typeof, alignof, o __attribute__. Ad esempio,
262
263 .. code-block:: c
264
265
266 s = sizeof(struct file);
267
268 Non aggiungete spazi attorno (dentro) ad un'espressione fra parentesi. Questo
269 esempio è **brutto**:
270
271 .. code-block:: c
272
273
274 s = sizeof( struct file );
275
276 Quando dichiarate un puntatore ad una variabile o una funzione che ritorna un
277 puntatore, il posto suggerito per l'asterisco ``*`` è adiacente al nome della
278 variabile o della funzione, e non adiacente al nome del tipo. Esempi:
279
280 .. code-block:: c
281
282
283 char *linux_banner;
284 unsigned long long memparse(char *ptr, char **retptr);
285 char *match_strdup(substring_t *s);
286
287 Usate uno spazio attorno (da ogni parte) alla maggior parte degli operatori
288 binari o ternari, come i seguenti::
289
290 = + - < > * / % | & ^ <= >= == != ? :
291
292 ma non mettete spazi dopo gli operatori unari::
293
294 & * + - ~ ! sizeof typeof alignof __attribute__ defined
295
296 nessuno spazio dopo l'operatore unario suffisso di incremento o decremento::
297
298 ++ --
299
300 nessuno spazio dopo l'operatore unario prefisso di incremento o decremento::
301
302 ++ --
303
304 e nessuno spazio attorno agli operatori dei membri di una struttura ``.`` e
305 ``->``.
306
307 Non lasciate spazi bianchi alla fine delle righe. Alcuni editor con
308 l'indentazione ``furba`` inseriranno gli spazi bianchi all'inizio di una nuova
309 riga in modo appropriato, quindi potrete scrivere la riga di codice successiva
310 immediatamente. Tuttavia, alcuni di questi stessi editor non rimuovono
311 questi spazi bianchi quando non scrivete nulla sulla nuova riga, ad esempio
312 perché volete lasciare una riga vuota. Il risultato è che finirete per avere
313 delle righe che contengono spazi bianchi in coda.
314
315 Git vi avviserà delle modifiche che aggiungono questi spazi vuoti di fine riga,
316 e può opzionalmente rimuoverli per conto vostro; tuttavia, se state applicando
317 una serie di modifiche, questo potrebbe far fallire delle modifiche successive
318 perché il contesto delle righe verrà cambiato.
319
320 4) Assegnare nomi
321 -----------------
322
323 C è un linguaggio spartano, e così dovrebbero esserlo i vostri nomi. Al
324 contrario dei programmatori Modula-2 o Pascal, i programmatori C non usano
325 nomi graziosi come ThisVariableIsATemporaryCounter. Un programmatore C
326 chiamerebbe questa variabile ``tmp``, che è molto più facile da scrivere e
327 non è una delle più difficili da capire.
328
329 TUTTAVIA, nonostante i nomi con notazione mista siano da condannare, i nomi
330 descrittivi per variabili globali sono un dovere. Chiamare una funzione
331 globale ``pippo`` è un insulto.
332
333 Le variabili GLOBALI (da usare solo se vi servono **davvero**) devono avere
334 dei nomi descrittivi, così come le funzioni globali. Se avete una funzione
335 che conta gli utenti attivi, dovreste chiamarla ``count_active_users()`` o
336 qualcosa di simile, **non** dovreste chiamarla ``cntusr()``.
337
338 Codificare il tipo di funzione nel suo nome (quella cosa chiamata notazione
339 ungherese) è stupido - il compilatore conosce comunque il tipo e
340 può verificarli, e inoltre confonde i programmatori.
341
342 Le variabili LOCALI dovrebbero avere nomi corti, e significativi. Se avete
343 un qualsiasi contatore di ciclo, probabilmente sarà chiamato ``i``.
344 Chiamarlo ``loop_counter`` non è produttivo, non ci sono possibilità che
345 ``i`` possa non essere capito. Analogamente, ``tmp`` può essere una qualsiasi
346 variabile che viene usata per salvare temporaneamente un valore.
347
348 Se avete paura di fare casino coi nomi delle vostre variabili locali, allora
349 avete un altro problema che è chiamato sindrome dello squilibrio dell'ormone
350 della crescita delle funzioni. Vedere il capitolo 6 (funzioni).
351
352 5) Definizione di tipi (typedef)
353 --------------------------------
354
355 Per favore non usate cose come ``vps_t``.
356 Usare il typedef per strutture e puntatori è uno **sbaglio**. Quando vedete:
357
358 .. code-block:: c
359
360 vps_t a;
361
362 nei sorgenti, cosa significa?
363 Se, invece, dicesse:
364
365 .. code-block:: c
366
367 struct virtual_container *a;
368
369 potreste dire cos'è effettivamente ``a``.
370
371 Molte persone pensano che la definizione dei tipi ``migliori la leggibilità``.
372 Non molto. Sono utili per:
373
374 (a) gli oggetti completamente opachi (dove typedef viene proprio usato allo
375 scopo di **nascondere** cosa sia davvero l'oggetto).
376
377 Esempio: ``pte_t`` eccetera sono oggetti opachi che potete usare solamente
378 con le loro funzioni accessorie.
379
380 .. note::
381 Gli oggetti opachi e le ``funzioni accessorie`` non sono, di per se,
382 una bella cosa. Il motivo per cui abbiamo cose come pte_t eccetera è
383 che davvero non c'è alcuna informazione portabile.
384
385 (b) i tipi chiaramente interi, dove l'astrazione **aiuta** ad evitare
386 confusione sul fatto che siano ``int`` oppure ``long``.
387
388 u8/u16/u32 sono typedef perfettamente accettabili, anche se ricadono
389 nella categoria (d) piuttosto che in questa.
390
391 .. note::
392
393 Ancora - dev'esserci una **ragione** per farlo. Se qualcosa è
394 ``unsigned long``, non c'è alcun bisogno di avere:
395
396 typedef unsigned long myfalgs_t;
397
398 ma se ci sono chiare circostanze in cui potrebbe essere ``unsigned int``
399 e in altre configurazioni ``unsigned long``, allora certamente typedef
400 è una buona scelta.
401
402 (c) quando di rado create letteralmente dei **nuovi** tipi su cui effettuare
403 verifiche.
404
405 (d) circostanze eccezionali, in cui si definiscono nuovi tipi identici a
406 quelli definiti dallo standard C99.
407
408 Nonostante ci voglia poco tempo per abituare occhi e cervello all'uso dei
409 tipi standard come ``uint32_t``, alcune persone ne obiettano l'uso.
410
411 Perciò, i tipi specifici di Linux ``u8/u16/u32/u64`` e i loro equivalenti
412 con segno, identici ai tipi standard, sono permessi- tuttavia, non sono
413 obbligatori per il nuovo codice.
414
415 (e) i tipi sicuri nella spazio utente.
416
417 In alcune strutture dati visibili dallo spazio utente non possiamo
418 richiedere l'uso dei tipi C99 e nemmeno i vari ``u32`` descritti prima.
419 Perciò, utilizziamo __u32 e tipi simili in tutte le strutture dati
420 condivise con lo spazio utente.
421
422 Magari ci sono altri casi validi, ma la regola di base dovrebbe essere di
423 non usare MAI MAI un typedef a meno che non rientri in una delle regole
424 descritte qui.
425
426 In generale, un puntatore, o una struttura a cui si ha accesso diretto in
427 modo ragionevole, non dovrebbero **mai** essere definite con un typedef.
428
429 6) Funzioni
430 -----------
431
432 Le funzioni dovrebbero essere brevi e carine, e fare una cosa sola. Dovrebbero
433 occupare uno o due schermi di testo (come tutti sappiamo, la dimensione
434 di uno schermo secondo ISO/ANSI è di 80x24), e fare una cosa sola e bene.
435
436 La massima lunghezza di una funziona è inversamente proporzionale alla sua
437 complessità e al livello di indentazione di quella funzione. Quindi, se avete
438 una funzione che è concettualmente semplice ma che è implementata come un
439 lunga (ma semplice) sequenza di caso-istruzione, dove avete molte piccole cose
440 per molti casi differenti, allora va bene avere funzioni più lunghe.
441
442 Comunque, se avete una funzione complessa e sospettate che uno studente
443 non particolarmente dotato del primo anno delle scuole superiori potrebbe
444 non capire cosa faccia la funzione, allora dovreste attenervi strettamente ai
445 limiti. Usate funzioni di supporto con nomi descrittivi (potete chiedere al
446 compilatore di renderle inline se credete che sia necessario per le
447 prestazioni, e probabilmente farà un lavoro migliore di quanto avreste potuto
448 fare voi).
449
450 Un'altra misura delle funzioni sono il numero di variabili locali. Non
451 dovrebbero eccedere le 5-10, oppure state sbagliando qualcosa. Ripensate la
452 funzione, e dividetela in pezzettini. Generalmente, un cervello umano può
453 seguire facilmente circa 7 cose diverse, di più lo confonderebbe. Lo sai
454 d'essere brillante, ma magari vorresti riuscire a capire cos'avevi fatto due
455 settimane prima.
456
457 Nei file sorgenti, separate le funzioni con una riga vuota. Se la funzione è
458 esportata, la macro **EXPORT** per questa funzione deve seguire immediatamente
459 la riga della parentesi graffa di chiusura. Ad esempio:
460
461 .. code-block:: c
462
463 int system_is_up(void)
464 {
465 return system_state == SYSTEM_RUNNING;
466 }
467 EXPORT_SYMBOL(system_is_up);
468
469 6.1) Prototipi di funzione
470 **************************
471
472 Nei prototipi di funzione, includete i nomi dei parametri e i loro tipi.
473 Nonostante questo non sia richiesto dal linguaggio C, in Linux viene preferito
474 perché è un modo semplice per aggiungere informazioni importanti per il
475 lettore.
476
477 Non usate la parola chiave ``extern`` con le dichiarazioni di funzione perché
478 rende le righe più lunghe e non è strettamente necessario.
479
480 Quando scrivete i prototipi di funzione mantenete `l'ordine degli elementi <https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_.
481
482 Prendiamo questa dichiarazione di funzione come esempio::
483
484 __init void * __must_check action(enum magic value, size_t size, u8 count,
485 char *fmt, ...) __printf(4, 5) __malloc;
486
487 L'ordine suggerito per gli elementi di un prototipo di funzione è il seguente:
488
489 - classe d'archiviazione (in questo caso ``static __always_inline``. Da notare
490 che ``__always_inline`` è tecnicamente un attributo ma che viene trattato come
491 ``inline``)
492 - attributi della classe di archiviazione (in questo caso ``__init``, in altre
493 parole la sezione, ma anche cose tipo ``__cold``)
494 - il tipo di ritorno (in questo caso, ``void *``)
495 - attributi per il valore di ritorno (in questo caso, ``__must_check``)
496 - il nome della funzione (in questo caso, ``action``)
497 - i parametri della funzione(in questo caso,
498 ``(enum magic value, size_t size, u8 count, char *fmt, ...)``,
499 da notare che va messo anche il nome del parametro)
500 - attributi dei parametri (in questo caso, ``__printf(4, 5)``)
501 - attributi per il comportamento della funzione (in questo caso, ``__malloc_``)
502
503 Notate che per la **definizione** di una funzione (il altre parole il corpo
504 della funzione), il compilatore non permette di usare gli attributi per i
505 parametri dopo i parametri. In questi casi, devono essere messi dopo gli
506 attributi della classe d'archiviazione (notate che la posizione di
507 ``__printf(4,5)`` cambia rispetto alla **dichiarazione**)::
508
509 static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value,
510 size_t size, u8 count, char *fmt, ...) __malloc
511 {
512 ...
513 }*)**``)**``)``)``*)``)``)``)``*``)``)``)*)
514
515 7) Centralizzare il ritorno delle funzioni
516 ------------------------------------------
517
518 Sebbene sia deprecata da molte persone, l'istruzione goto è impiegata di
519 frequente dai compilatori sotto forma di salto incondizionato.
520
521 L'istruzione goto diventa utile quando una funzione ha punti d'uscita multipli
522 e vanno eseguite alcune procedure di pulizia in comune. Se non è necessario
523 pulire alcunché, allora ritornate direttamente.
524
525 Assegnate un nome all'etichetta di modo che suggerisca cosa fa la goto o
526 perché esiste. Un esempio di un buon nome potrebbe essere ``out_free_buffer:``
527 se la goto libera (free) un ``buffer``. Evitate l'uso di nomi GW-BASIC come
528 ``err1:`` ed ``err2:``, potreste doverli riordinare se aggiungete o rimuovete
529 punti d'uscita, e inoltre rende difficile verificarne la correttezza.
530
531 I motivo per usare le goto sono:
532
533 - i salti incondizionati sono più facili da capire e seguire
534 - l'annidamento si riduce
535 - si evita di dimenticare, per errore, di aggiornare un singolo punto d'uscita
536 - aiuta il compilatore ad ottimizzare il codice ridondante ;)
537
538 .. code-block:: c
539
540 int fun(int a)
541 {
542 int result = 0;
543 char *buffer;
544
545 buffer = kmalloc(SIZE, GFP_KERNEL);
546 if (!buffer)
547 return -ENOMEM;
548
549 if (condition1) {
550 while (loop1) {
551 ...
552 }
553 result = 1;
554 goto out_free_buffer;
555 }
556 ...
557 out_free_buffer:
558 kfree(buffer);
559 return result;
560 }
561
562 Un baco abbastanza comune di cui bisogna prendere nota è il ``one err bugs``
563 che assomiglia a questo:
564
565 .. code-block:: c
566
567 err:
568 kfree(foo->bar);
569 kfree(foo);
570 return ret;
571
572 Il baco in questo codice è che in alcuni punti d'uscita la variabile ``foo`` è
573 NULL. Normalmente si corregge questo baco dividendo la gestione dell'errore in
574 due parti ``err_free_bar:`` e ``err_free_foo:``:
575
576 .. code-block:: c
577
578 err_free_bar:
579 kfree(foo->bar);
580 err_free_foo:
581 kfree(foo);
582 return ret;
583
584 Idealmente, dovreste simulare condizioni d'errore per verificare i vostri
585 percorsi d'uscita.
586
587
588 8) Commenti
589 -----------
590
591 I commenti sono una buona cosa, ma c'è anche il rischio di esagerare. MAI
592 spiegare COME funziona il vostro codice in un commento: è molto meglio
593 scrivere il codice di modo che il suo funzionamento sia ovvio, inoltre
594 spiegare codice scritto male è una perdita di tempo.
595
596 Solitamente, i commenti devono dire COSA fa il codice, e non COME lo fa.
597 Inoltre, cercate di evitare i commenti nel corpo della funzione: se la
598 funzione è così complessa che dovete commentarla a pezzi, allora dovreste
599 tornare al punto 6 per un momento. Potete mettere dei piccoli commenti per
600 annotare o avvisare il lettore circa un qualcosa di particolarmente arguto
601 (o brutto), ma cercate di non esagerare. Invece, mettete i commenti in
602 testa alla funzione spiegando alle persone cosa fa, e possibilmente anche
603 il PERCHÉ.
604
605 Per favore, quando commentate una funzione dell'API del kernel usate il
606 formato kernel-doc. Per maggiori dettagli, leggete i file in
607 :ref::ref:`Documentation/translations/it_IT/doc-guide/ <it_doc_guide>` e in
608 ``script/kernel-doc``.
609
610 Lo stile preferito per i commenti più lunghi (multi-riga) è:
611
612 .. code-block:: c
613
614 /*
615 * This is the preferred style for multi-line
616 * comments in the Linux kernel source code.
617 * Please use it consistently.
618 *
619 * Description: A column of asterisks on the left side,
620 * with beginning and ending almost-blank lines.
621 */
622
623 È anche importante commentare i dati, sia per i tipi base che per tipi
624 derivati. A questo scopo, dichiarate un dato per riga (niente virgole
625 per una dichiarazione multipla). Questo vi lascerà spazio per un piccolo
626 commento per spiegarne l'uso.
627
628
629 9) Avete fatto un pasticcio
630 ---------------------------
631
632 Va bene, li facciamo tutti. Probabilmente vi è stato detto dal vostro
633 aiutante Unix di fiducia che ``GNU emacs`` formatta automaticamente il
634 codice C per conto vostro, e avete notato che sì, in effetti lo fa, ma che
635 i modi predefiniti non sono proprio allettanti (infatti, sono peggio che
636 premere tasti a caso - un numero infinito di scimmie che scrivono in
637 GNU emacs non faranno mai un buon programma).
638
639 Quindi, potete sbarazzarvi di GNU emacs, o riconfigurarlo con valori più
640 sensati. Per fare quest'ultima cosa, potete appiccicare il codice che
641 segue nel vostro file .emacs:
642
643 .. code-block:: elisp
644
645 (defun c-lineup-arglist-tabs-only (ignored)
646 "Line up argument lists by tabs, not spaces"
647 (let* ((anchor (c-langelem-pos c-syntactic-element))
648 (column (c-langelem-2nd-pos c-syntactic-element))
649 (offset (- (1+ column) anchor))
650 (steps (floor offset c-basic-offset)))
651 (* (max steps 1)
652 c-basic-offset)))
653
654 (dir-locals-set-class-variables
655 'linux-kernel
656 '((c-mode . (
657 (c-basic-offset . 8)
658 (c-label-minimum-indentation . 0)
659 (c-offsets-alist . (
660 (arglist-close . c-lineup-arglist-tabs-only)
661 (arglist-cont-nonempty .
662 (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only))
663 (arglist-intro . +)
664 (brace-list-intro . +)
665 (c . c-lineup-C-comments)
666 (case-label . 0)
667 (comment-intro . c-lineup-comment)
668 (cpp-define-intro . +)
669 (cpp-macro . -1000)
670 (cpp-macro-cont . +)
671 (defun-block-intro . +)
672 (else-clause . 0)
673 (func-decl-cont . +)
674 (inclass . +)
675 (inher-cont . c-lineup-multi-inher)
676 (knr-argdecl-intro . 0)
677 (label . -1000)
678 (statement . 0)
679 (statement-block-intro . +)
680 (statement-case-intro . +)
681 (statement-cont . +)
682 (substatement . +)
683 ))
684 (indent-tabs-mode . t)
685 (show-trailing-whitespace . t)
686 ))))
687
688 (dir-locals-set-directory-class
689 (expand-file-name "~/src/linux-trees")
690 'linux-kernel)
691
692 Questo farà funzionare meglio emacs con lo stile del kernel per i file che
693 si trovano nella cartella ``~/src/linux-trees``.
694
695 Ma anche se doveste fallire nell'ottenere una formattazione sensata in emacs
696 non tutto è perduto: usate ``indent``.
697
698 Ora, ancora, GNU indent ha la stessa configurazione decerebrata di GNU emacs,
699 ed è per questo che dovete passargli alcune opzioni da riga di comando.
700 Tuttavia, non è così terribile, perché perfino i creatori di GNU indent
701 riconoscono l'autorità di K&R (le persone del progetto GNU non sono cattive,
702 sono solo mal indirizzate sull'argomento), quindi date ad indent le opzioni
703 ``-kr -i8`` (che significa ``K&R, 8 caratteri di indentazione``), o utilizzate
704 ``scripts/Lindent`` che indenterà usando l'ultimo stile.
705
706 ``indent`` ha un sacco di opzioni, e specialmente quando si tratta di
707 riformattare i commenti dovreste dare un'occhiata alle pagine man.
708 Ma ricordatevi: ``indent`` non è un correttore per una cattiva programmazione.
709
710 Da notare che potete utilizzare anche ``clang-format`` per aiutarvi con queste
711 regole, per riformattare rapidamente ad automaticamente alcune parti del
712 vostro codice, e per revisionare interi file al fine di identificare errori
713 di stile, refusi e possibilmente anche delle migliorie. È anche utile per
714 ordinare gli ``#include``, per allineare variabili/macro, per ridistribuire
715 il testo e altre cose simili.
716 Per maggiori dettagli, consultate il file
717 :ref:`Documentation/translations/it_IT/dev-tools/clang-format.rst <it_clangformat>`.
718
719 Se utilizzate un programma compatibile con EditorConfig, allora alcune
720 configurazioni basilari come l'indentazione e la fine delle righe verranno
721 applicate automaticamente. Per maggiori informazioni consultate la pagina:
722 https://editorconfig.org/
723
724 10) File di configurazione Kconfig
725 ----------------------------------
726
727 Per tutti i file di configurazione Kconfig* che si possono trovare nei
728 sorgenti, l'indentazione è un po' differente. Le linee dopo un ``config``
729 sono indentate con un tab, mentre il testo descrittivo è indentato di
730 ulteriori due spazi. Esempio::
731
732 config AUDIT
733 bool "Auditing support"
734 depends on NET
735 help
736 Enable auditing infrastructure that can be used with another
737 kernel subsystem, such as SELinux (which requires this for
738 logging of avc messages output). Does not do system-call
739 auditing without CONFIG_AUDITSYSCALL.
740
741 Le funzionalità davvero pericolose (per esempio il supporto alla scrittura
742 per certi filesystem) dovrebbero essere dichiarate chiaramente come tali
743 nella stringa di titolo::
744
745 config ADFS_FS_RW
746 bool "ADFS write support (DANGEROUS)"
747 depends on ADFS_FS
748 ...
749
750 Per la documentazione completa sui file di configurazione, consultate
751 il documento Documentation/kbuild/kconfig-language.rst
752
753
754 11) Strutture dati
755 ------------------
756
757 Le strutture dati che hanno una visibilità superiore al contesto del
758 singolo thread in cui vengono create e distrutte, dovrebbero sempre
759 avere un contatore di riferimenti. Nel kernel non esiste un
760 *garbage collector* (e fuori dal kernel i *garbage collector* sono lenti
761 e inefficienti), questo significa che **dovete** assolutamente avere un
762 contatore di riferimenti per ogni cosa che usate.
763
764 Avere un contatore di riferimenti significa che potete evitare la
765 sincronizzazione e permette a più utenti di accedere alla struttura dati
766 in parallelo - e non doversi preoccupare di una struttura dati che
767 improvvisamente sparisce dalla loro vista perché il loro processo dormiva
768 o stava facendo altro per un attimo.
769
770 Da notare che la sincronizzazione **non** si sostituisce al conteggio dei
771 riferimenti. La sincronizzazione ha lo scopo di mantenere le strutture
772 dati coerenti, mentre il conteggio dei riferimenti è una tecnica di gestione
773 della memoria. Solitamente servono entrambe le cose, e non vanno confuse fra
774 di loro.
775
776 Quando si hanno diverse classi di utenti, le strutture dati possono avere
777 due livelli di contatori di riferimenti. Il contatore di classe conta
778 il numero dei suoi utenti, e il contatore globale viene decrementato una
779 sola volta quando il contatore di classe va a zero.
780
781 Un esempio di questo tipo di conteggio dei riferimenti multi-livello può
782 essere trovato nella gestore della memoria (``struct mm_sturct``: mm_user e
783 mm_count), e nel codice dei filesystem (``struct super_block``: s_count e
784 s_active).
785
786 Ricordatevi: se un altro thread può trovare la vostra struttura dati, e non
787 avete un contatore di riferimenti per essa, quasi certamente avete un baco.
788
789 12) Macro, enumerati e RTL
790 ---------------------------
791
792 I nomi delle macro che definiscono delle costanti e le etichette degli
793 enumerati sono scritte in maiuscolo.
794
795 .. code-block:: c
796
797 #define CONSTANT 0x12345
798
799 Gli enumerati sono da preferire quando si definiscono molte costanti correlate.
800
801 I nomi delle macro in MAIUSCOLO sono preferibili ma le macro che assomigliano
802 a delle funzioni possono essere scritte in minuscolo.
803
804 Generalmente, le funzioni inline sono preferibili rispetto alle macro che
805 sembrano funzioni.
806
807 Le macro che contengono più istruzioni dovrebbero essere sempre chiuse in un
808 blocco do - while:
809
810 .. code-block:: c
811
812 #define macrofun(a, b, c) \
813 do { \
814 if (a == 5) \
815 do_this(b, c); \
816 } while (0)
817
818 Le macro che sembrano funzioni con parametri non usati dovrebbero essere
819 sostituite da funzioni inline per evitare il problema.
820
821 .. code-block:: c
822
823 static inline void fun(struct foo *foo)
824 {
825 }
826
827 Per motivi storici, molti file usano ancora l'approccio "cast a (void)" per
828 valutare i parametri. Tuttavia, non è raccomandato. Le funzioni inline risolvono
829 i problemi di "espressioni con effetti avversi valutate più di una volta",
830 variabili non utilizzate, e in genere per qualche motivo sono documentate
831 meglio.
832
833 .. code-block:: c
834
835 /*
836 * Avoid doing this whenever possible and instead opt for static
837 * inline functions
838 */
839 #define macrofun(foo) do { (void) (foo); } while (0)
840
841 Cose da evitare quando si usano le macro:
842
843 1) le macro che hanno effetti sul flusso del codice:
844
845 .. code-block:: c
846
847 #define FOO(x) \
848 do { \
849 if (blah(x) < 0) \
850 return -EBUGGERED; \
851 } while (0)
852
853 sono **proprio** una pessima idea. Sembra una chiamata a funzione ma termina
854 la funzione chiamante; non cercate di rompere il decodificatore interno di
855 chi legge il codice.
856
857 2) le macro che dipendono dall'uso di una variabile locale con un nome magico:
858
859 .. code-block:: c
860
861 #define FOO(val) bar(index, val)
862
863 potrebbe sembrare una bella cosa, ma è dannatamente confusionario quando uno
864 legge il codice e potrebbe romperlo con una cambiamento che sembra innocente.
865
866 3) le macro con argomenti che sono utilizzati come l-values; questo potrebbe
867 ritorcervisi contro se qualcuno, per esempio, trasforma FOO in una funzione
868 inline.
869
870 4) dimenticatevi delle precedenze: le macro che definiscono espressioni devono
871 essere racchiuse fra parentesi. State attenti a problemi simili con le macro
872 parametrizzate.
873
874 .. code-block:: c
875
876 #define CONSTANT 0x4000
877 #define CONSTEXP (CONSTANT | 3)
878
879 5) collisione nello spazio dei nomi quando si definisce una variabile locale in
880 una macro che sembra una funzione:
881
882 .. code-block:: c
883
884 #define FOO(x) \
885 ({ \
886 typeof(x) ret; \
887 ret = calc_ret(x); \
888 (ret); \
889 })
890
891 ret è un nome comune per una variabile locale - __foo_ret difficilmente
892 andrà in conflitto con una variabile già esistente.
893
894 Il manuale di cpp si occupa esaustivamente delle macro. Il manuale di sviluppo
895 di gcc copre anche l'RTL che viene usato frequentemente nel kernel per il
896 linguaggio assembler.
897
898 13) Visualizzare i messaggi del kernel
899 --------------------------------------
900
901 Agli sviluppatori del kernel piace essere visti come dotti. Tenete un occhio
902 di riguardo per l'ortografia e farete una belle figura. In inglese, evitate
903 l'uso incorretto di abbreviazioni come ``dont``: usate ``do not`` oppure
904 ``don't``. Scrivete messaggi concisi, chiari, e inequivocabili.
905
906 I messaggi del kernel non devono terminare con un punto fermo.
907
908 Scrivere i numeri fra parentesi (%d) non migliora alcunché e per questo
909 dovrebbero essere evitati.
910
911 Ci sono alcune macro per la diagnostica in <linux/dev_printk.h> che dovreste
912 usare per assicurarvi che i messaggi vengano associati correttamente ai
913 dispositivi e ai driver, e che siano etichettati correttamente: dev_err(),
914 dev_warn(), dev_info(), e così via. Per messaggi che non sono associati ad
915 alcun dispositivo, <linux/printk.h> definisce pr_info(), pr_warn(), pr_err(),
916 eccetera. Quando tutto funziona correttamente, non dovrebbero esserci stampe,
917 per cui preferite dev_dbg/pr_debug a meno che non sia qualcosa di sbagliato
918 da segnalare.
919
920 Tirar fuori un buon messaggio di debug può essere una vera sfida; e quando
921 l'avete può essere d'enorme aiuto per risolvere problemi da remoto.
922 Tuttavia, i messaggi di debug sono gestiti differentemente rispetto agli
923 altri. Le funzioni pr_XXX() stampano incondizionatamente ma pr_debug() no;
924 essa non viene compilata nella configurazione predefinita, a meno che
925 DEBUG o CONFIG_DYNAMIC_DEBUG non vengono impostati. Questo vale anche per
926 dev_dbg() e in aggiunta VERBOSE_DEBUG per aggiungere i messaggi dev_vdbg().
927
928 Molti sottosistemi hanno delle opzioni di debug in Kconfig che aggiungono
929 -DDEBUG nei corrispettivi Makefile, e in altri casi aggiungono #define DEBUG
930 in specifici file. Infine, quando un messaggio di debug dev'essere stampato
931 incondizionatamente, per esempio perché siete già in una sezione di debug
932 racchiusa in #ifdef, potete usare printk(KERN_DEBUG ...).
933
934 14) Assegnare memoria
935 ---------------------
936
937 Il kernel fornisce i seguenti assegnatori ad uso generico:
938 kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc(), e vzalloc().
939 Per maggiori informazioni, consultate la documentazione dell'API:
940 :ref:`Documentation/translations/it_IT/core-api/memory-allocation.rst <it_memory_allocation>`
941
942 Il modo preferito per passare la dimensione di una struttura è il seguente:
943
944 .. code-block:: c
945
946 p = kmalloc(sizeof(*p), ...);
947
948 La forma alternativa, dove il nome della struttura viene scritto interamente,
949 peggiora la leggibilità e introduce possibili bachi quando il tipo di
950 puntatore cambia tipo ma il corrispondente sizeof non viene aggiornato.
951
952 Il valore di ritorno è un puntatore void, effettuare un cast su di esso è
953 ridondante. La conversione fra un puntatore void e un qualsiasi altro tipo
954 di puntatore è garantito dal linguaggio di programmazione C.
955
956 Il modo preferito per assegnare un vettore è il seguente:
957
958 .. code-block:: c
959
960 p = kmalloc_array(n, sizeof(...), ...);
961
962 Il modo preferito per assegnare un vettore a zero è il seguente:
963
964 .. code-block:: c
965
966 p = kcalloc(n, sizeof(...), ...);
967
968 Entrambe verificano la condizione di overflow per la dimensione
969 d'assegnamento n * sizeof(...), se accade ritorneranno NULL.
970
971 Questi allocatori generici producono uno *stack dump* in caso di fallimento
972 a meno che non venga esplicitamente specificato __GFP_NOWARN. Quindi, nella
973 maggior parte dei casi, è inutile stampare messaggi aggiuntivi quando uno di
974 questi allocatori ritornano un puntatore NULL.
975
976 15) Il morbo inline
977 -------------------
978
979 Sembra che ci sia la percezione errata che gcc abbia una qualche magica
980 opzione "rendimi più veloce" chiamata ``inline``. In alcuni casi l'uso di
981 inline è appropriato (per esempio in sostituzione delle macro, vedi
982 capitolo 12), ma molto spesso non lo è. L'uso abbondante della parola chiave
983 inline porta ad avere un kernel più grande, che si traduce in un sistema nel
984 suo complesso più lento per via di una cache per le istruzioni della CPU più
985 grande e poi semplicemente perché ci sarà meno spazio disponibile per una
986 pagina di cache. Pensateci un attimo; una fallimento nella cache causa una
987 ricerca su disco che può tranquillamente richiedere 5 millisecondi. Ci sono
988 TANTI cicli di CPU che potrebbero essere usati in questi 5 millisecondi.
989
990 Spesso le persone dicono che aggiungere inline a delle funzioni dichiarate
991 static e utilizzare una sola volta è sempre una scelta vincente perché non
992 ci sono altri compromessi. Questo è tecnicamente vero ma gcc è in grado di
993 trasformare automaticamente queste funzioni in inline; i problemi di
994 manutenzione del codice per rimuovere gli inline quando compare un secondo
995 utente surclassano il potenziale vantaggio nel suggerire a gcc di fare una
996 cosa che avrebbe fatto comunque.
997
998 16) Nomi e valori di ritorno delle funzioni
999 -------------------------------------------
1001 Le funzioni possono ritornare diversi tipi di valori, e uno dei più comuni
1002 è quel valore che indica se una funzione ha completato con successo o meno.
1003 Questo valore può essere rappresentato come un codice di errore intero
1004 (-Exxx = fallimento, 0 = successo) oppure un booleano di successo
1005 (0 = fallimento, non-zero = successo).
1007 Mischiare questi due tipi di rappresentazioni è un terreno fertile per
1008 i bachi più insidiosi. Se il linguaggio C includesse una forte distinzione
1009 fra gli interi e i booleani, allora il compilatore potrebbe trovare questi
1010 errori per conto nostro ... ma questo non c'è. Per evitare di imbattersi
1011 in questo tipo di baco, seguite sempre la seguente convenzione::
1013 Se il nome di una funzione è un'azione o un comando imperativo,
1014 essa dovrebbe ritornare un codice di errore intero. Se il nome
1015 è un predicato, la funzione dovrebbe ritornare un booleano di
1016 "successo"
1018 Per esempio, ``add work`` è un comando, e la funzione add_work() ritorna 0
1019 in caso di successo o -EBUSY in caso di fallimento. Allo stesso modo,
1020 ``PCI device present`` è un predicato, e la funzione pci_dev_present() ritorna
1021 1 se trova il dispositivo corrispondente con successo, altrimenti 0.
1023 Tutte le funzioni esportate (EXPORT) devono rispettare questa convenzione, e
1024 così dovrebbero anche tutte le funzioni pubbliche. Le funzioni private
1025 (static) possono non seguire questa convenzione, ma è comunque raccomandato
1026 che lo facciano.
1028 Le funzioni il cui valore di ritorno è il risultato di una computazione,
1029 piuttosto che l'indicazione sul successo di tale computazione, non sono
1030 soggette a questa regola. Solitamente si indicano gli errori ritornando un
1031 qualche valore fuori dai limiti. Un tipico esempio è quello delle funzioni
1032 che ritornano un puntatore; queste utilizzano NULL o ERR_PTR come meccanismo
1033 di notifica degli errori.
1035 17) L'uso di bool
1036 -----------------
1038 Nel kernel Linux il tipo bool deriva dal tipo _Bool dello standard C99.
1039 Un valore bool può assumere solo i valori 0 o 1, e implicitamente o
1040 esplicitamente la conversione a bool converte i valori in vero (*true*) o
1041 falso (*false*). Quando si usa un tipo bool il costrutto !! non sarà più
1042 necessario, e questo va ad eliminare una certa serie di bachi.
1044 Quando si usano i valori booleani, dovreste utilizzare le definizioni di true
1045 e false al posto dei valori 1 e 0.
1047 Per il valore di ritorno delle funzioni e per le variabili sullo stack, l'uso
1048 del tipo bool è sempre appropriato. L'uso di bool viene incoraggiato per
1049 migliorare la leggibilità e spesso è molto meglio di 'int' nella gestione di
1050 valori booleani.
1052 Non usate bool se per voi sono importanti l'ordine delle righe di cache o
1053 la loro dimensione; la dimensione e l'allineamento cambia a seconda
1054 dell'architettura per la quale è stato compilato. Le strutture che sono state
1055 ottimizzate per l'allineamento o la dimensione non dovrebbero usare bool.
1057 Se una struttura ha molti valori true/false, considerate l'idea di raggrupparli
1058 in un intero usando campi da 1 bit, oppure usate un tipo dalla larghezza fissa,
1059 come u8.
1061 Come per gli argomenti delle funzioni, molti valori true/false possono essere
1062 raggruppati in un singolo argomento a bit denominato 'flags'; spesso 'flags' è
1063 un'alternativa molto più leggibile se si hanno valori costanti per true/false.
1065 Detto ciò, un uso parsimonioso di bool nelle strutture dati e negli argomenti
1066 può migliorare la leggibilità.
1068 18) Non reinventate le macro del kernel
1069 ---------------------------------------
1071 Il file di intestazione include/linux/kernel.h contiene un certo numero
1072 di macro che dovreste usare piuttosto che implementarne una qualche variante.
1073 Per esempio, se dovete calcolare la lunghezza di un vettore, sfruttate la
1074 macro:
1076 .. code-block:: c
1078 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
1080 Analogamente, se dovete calcolare la dimensione di un qualche campo di una
1081 struttura, usate
1083 .. code-block:: c
1085 #define sizeof_field(t, f) (sizeof(((t*)0)->f))
1087 Ci sono anche le macro min() e max() che, se vi serve, effettuano un controllo
1088 rigido sui tipi. Sentitevi liberi di leggere attentamente questo file
1089 d'intestazione per scoprire cos'altro è stato definito che non dovreste
1090 reinventare nel vostro codice.
1092 19) Linee di configurazione degli editor e altre schifezze
1093 -----------------------------------------------------------
1095 Alcuni editor possono interpretare dei parametri di configurazione integrati
1096 nei file sorgenti e indicati con dai marcatori speciali. Per esempio, emacs
1097 interpreta le linee marcate nel seguente modo:
1099 .. code-block:: c
1101 -*- mode: c -*-
1103 O come queste:
1105 .. code-block:: c
1107 /*
1108 Local Variables:
1109 compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"
1110 End:
1111 */
1113 Vim interpreta i marcatori come questi:
1115 .. code-block:: c
1117 /* vim:set sw=8 noet */
1119 Non includete nessuna di queste cose nei file sorgenti. Le persone hanno le
1120 proprie configurazioni personali per l'editor, e i vostri sorgenti non
1121 dovrebbero sovrascrivergliele. Questo vale anche per i marcatori
1122 d'indentazione e di modalità d'uso. Le persone potrebbero aver configurato una
1123 modalità su misura, oppure potrebbero avere qualche altra magia per far
1124 funzionare bene l'indentazione.
1126 20) Inline assembly
1127 -------------------
1129 Nel codice specifico per un'architettura, potreste aver bisogno di codice
1130 *inline assembly* per interfacciarvi col processore o con una funzionalità
1131 specifica della piattaforma. Non esitate a farlo quando è necessario.
1132 Comunque, non usatele gratuitamente quando il C può fare la stessa cosa.
1133 Potete e dovreste punzecchiare l'hardware in C quando è possibile.
1135 Considerate la scrittura di una semplice funzione che racchiude pezzi comuni
1136 di codice assembler piuttosto che continuare a riscrivere delle piccole
1137 varianti. Ricordatevi che l' *inline assembly* può utilizzare i parametri C.
1139 Il codice assembler più corposo e non banale dovrebbe andare nei file .S,
1140 coi rispettivi prototipi C definiti nei file d'intestazione. I prototipi C
1141 per le funzioni assembler dovrebbero usare ``asmlinkage``.
1143 Potreste aver bisogno di marcare il vostro codice asm come volatile al fine
1144 d'evitare che GCC lo rimuova quando pensa che non ci siano effetti collaterali.
1145 Non c'è sempre bisogno di farlo, e farlo quando non serve limita le
1146 ottimizzazioni.
1148 Quando scrivete una singola espressione *inline assembly* contenente più
1149 istruzioni, mettete ognuna di queste istruzioni in una stringa e riga diversa;
1150 ad eccezione dell'ultima stringa/istruzione, ognuna deve terminare con ``\n\t``
1151 al fine di allineare correttamente l'assembler che verrà generato:
1153 .. code-block:: c
1155 asm ("magic %reg1, #42\n\t"
1156 "more_magic %reg2, %reg3"
1157 : /* outputs */ : /* inputs */ : /* clobbers */);
1159 21) Compilazione sotto condizione
1160 ---------------------------------
1162 Ovunque sia possibile, non usate le direttive condizionali del preprocessore
1163 (#if, #ifdef) nei file .c; farlo rende il codice difficile da leggere e da
1164 seguire. Invece, usate queste direttive nei file d'intestazione per definire
1165 le funzioni usate nei file .c, fornendo i relativi stub nel caso #else,
1166 e quindi chiamate queste funzioni senza condizioni di preprocessore. Il
1167 compilatore non produrrà alcun codice per le funzioni stub, produrrà gli
1168 stessi risultati, e la logica rimarrà semplice da seguire.
1170 È preferibile non compilare intere funzioni piuttosto che porzioni d'esse o
1171 porzioni d'espressioni. Piuttosto che mettere una ifdef in un'espressione,
1172 fattorizzate parte dell'espressione, o interamente, in funzioni e applicate
1173 la direttiva condizionale su di esse.
1175 Se avete una variabile o funzione che potrebbe non essere usata in alcune
1176 configurazioni, e quindi il compilatore potrebbe avvisarvi circa la definizione
1177 inutilizzata, marcate questa definizione come __maybe_unused piuttosto che
1178 racchiuderla in una direttiva condizionale del preprocessore. (Comunque,
1179 se una variabile o funzione è *sempre* inutilizzata, rimuovetela).
1181 Nel codice, dov'è possibile, usate la macro IS_ENABLED per convertire i
1182 simboli Kconfig in espressioni booleane C, e quindi usatela nelle classiche
1183 condizioni C:
1185 .. code-block:: c
1187 if (IS_ENABLED(CONFIG_SOMETHING)) {
1188 ...
1189 }
1191 Il compilatore valuterà la condizione come costante (constant-fold), e quindi
1192 includerà o escluderà il blocco di codice come se fosse in un #ifdef, quindi
1193 non ne aumenterà il tempo di esecuzione. Tuttavia, questo permette al
1194 compilatore C di vedere il codice nel blocco condizionale e verificarne la
1195 correttezza (sintassi, tipi, riferimenti ai simboli, eccetera). Quindi
1196 dovete comunque utilizzare #ifdef se il codice nel blocco condizionale esiste
1197 solo quando la condizione è soddisfatta.
1199 Alla fine di un blocco corposo di #if o #ifdef (più di alcune linee),
1200 mettete un commento sulla stessa riga di #endif, annotando la condizione
1201 che termina. Per esempio:
1203 .. code-block:: c
1205 #ifdef CONFIG_SOMETHING
1206 ...
1207 #endif /* CONFIG_SOMETHING */
1209 Appendice I) riferimenti
1210 ------------------------
1212 The C Programming Language, Second Edition
1213 by Brian W. Kernighan and Dennis M. Ritchie.
1214 Prentice Hall, Inc., 1988.
1215 ISBN 0-13-110362-8 (paperback), 0-13-110370-9 (hardback).
1217 The Practice of Programming
1218 by Brian W. Kernighan and Rob Pike.
1219 Addison-Wesley, Inc., 1999.
1220 ISBN 0-201-61586-X.
1222 Manuali GNU - nei casi in cui sono compatibili con K&R e questo documento -
1223 per indent, cpp, gcc e i suoi dettagli interni, tutto disponibile qui
1224 https://www.gnu.org/manual/
1226 WG14 è il gruppo internazionale di standardizzazione per il linguaggio C,
1227 URL: https://www.open-std.org/JTC1/SC22/WG14/
1229 Kernel CodingStyle, by [email protected] at OLS 2002:
1230 http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

문서의 목적과 들여쓰기

1-105

이 문서는 Linux 커널에서 선호하는 코딩 형식을 간결하게 설명한다. 코딩 스타일은 개인 취향의 문제가 될 수 있지만, 커널은 여러 사람이 오랫동안 함께 수정하는 코드이므로 하나의 일관된 형식을 사용해야 한다. GNU 코딩 표준을 읽고 혼란스러웠다면 그 내용을 잊고 이 문서를 따르라는 도입부의 농담도 원문의 어조 그대로 이해하면 된다.

들여쓰기는 탭 문자이며 탭 너비는 8자다. 8자는 우연히 정한 값이 아니다. 조건문과 반복문이 여러 단계 겹치면 코드가 화면 오른쪽으로 빠르게 밀려나므로, 함수가 지나치게 복잡해졌다는 사실이 눈에 띈다. 들여쓰기가 세 단계보다 깊어졌다면 하위 동작을 별도 함수로 나누는 편이 낫다.

switch 문의 case 레이블은 switch와 같은 열에 둔다. 논리적으로는 case가 switch 내부에 있지만, 8자 탭을 사용하는 환경에서는 이 배치가 각 분기와 분기 본문을 가장 분명하게 구별한다.

switch (suffix) {
case 'G':
case 'g':
	mem <<= 30;
	break;
case 'M':
case 'm':
	mem <<= 20;
	break;
case 'K':
case 'k':
	mem <<= 10;
	fallthrough;
default:
	break;
}

한 줄에 문장을 두 개 이상 쓰지 않는다. 아래 첫 예제는 do_this()만 조건에 포함되고 다음 문장은 항상 실행되지만, 화면에서는 둘 다 조건에 속한 것처럼 보인다. 두 번째 예제처럼 콤마 연산자로 중괄호를 피하는 방식도 읽는 사람에게 실행 경계를 숨긴다.

/* 잘못된 예 */
if (condition) do_this;
  do_something_everytime;

/* 이 방법으로 중괄호를 피하지 않는다. */
if (condition)
	do_this(), do_that();

/* 여러 문장은 명시적인 블록으로 묶는다. */
if (condition) {
	do_this();
	do_that();
}

복잡한 표현식과 여러 대입을 한 줄에 압축하지 않는다. 컴파일러가 이해할 수 있다는 사실보다 사람이 코드를 즉시 검토할 수 있는지가 중요하다. 주석, 문서, Kconfig처럼 탭이 적절하지 않은 영역을 제외하면 들여쓰기에 공백을 사용하지 않으며, 줄 끝 공백도 남기지 않는다.

.. include:: ../disclaimer-ita.rst

:Original: :ref:`Documentation/process/coding-style.rst <codingstyle>`
:Translator: Federico Vaga <[email protected]>

.. _it_codingstyle:

Stile del codice per il kernel Linux
====================================

Questo è 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.

La prima cosa che suggerisco è quella di stamparsi una copia degli standard
di codifica GNU e di NON leggerla.  Bruciatela, è un grande gesto simbolico.

Comunque, ecco i punti:

1) Indentazione
---------------

La 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.

Motivazione: 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.

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.

In 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.

Al 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.:

.. code-block:: c

	switch (suffix) {
	case 'G':
	case 'g':
		mem <<= 30;
		break;
	case 'M':
	case 'm':
		mem <<= 20;
		break;
	case 'K':
	case 'k':
		mem <<= 10;
		fallthrough;
	default:
		break;
	}

A meno che non vogliate nascondere qualcosa, non mettete più istruzioni sulla
stessa riga:

.. code-block:: c

	if (condition) do_this;
	  do_something_everytime;

Non usate le virgole per evitare le parentesi:

.. code-block:: c

	if (condition)
               do_this(), do_that();

Invece, usate sempre le parentesi per racchiudere più istruzioni.

.. code-block:: c

	if (condition) {
               do_this();
               do_that();
       }

Non mettete nemmeno più assegnamenti sulla stessa riga.  Lo stile del kernel
è ultrasemplice.  Evitate espressioni intricate.


Al 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.

Procuratevi un buon editor di testo e non lasciate spazi bianchi alla fine
delle righe.

긴 줄과 문자열 나누기

106-128

코딩 스타일의 목적은 읽기 쉽고 유지보수하기 쉬운 코드를 만드는 것이다. 한 줄은 가급적 80열을 넘기지 않는다. 다만 줄을 억지로 나누어 의미 단위가 깨지거나 검색과 이해가 오히려 어려워진다면, 약간 긴 줄을 허용하는 편이 낫다.

줄을 나눌 때 이어지는 부분은 원래 줄보다 짧고 오른쪽에 놓여야 한다. 함수 인수는 여는 괄호 다음 위치에 맞추어 정렬한다. 이 원칙은 C 소스뿐 아니라 헤더 파일에도 적용한다.

printk 계열이 출력하는 사용자 가시 문자열은 여러 줄의 문자열 리터럴로 쪼개지 않는다. 커널 로그의 정확한 문구를 grep으로 찾는 일이 많기 때문에, 소스에서 검색 가능한 하나의 문자열로 유지해야 한다.

2) Spezzare righe lunghe e stringhe
-----------------------------------

Lo stile del codice riguarda la leggibilità e la manutenibilità utilizzando
strumenti comuni.

Come limite di riga si preferiscono le 80 colonne.

Espressioni 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.

I 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.

Lo stesso si applica, nei file d'intestazione, alle funzioni con una
lista di argomenti molto lunga.

Tuttavia, non spezzettate mai le stringhe visibili agli utenti come i
messaggi di printk, questo perché inibireste la possibilità
d'utilizzare grep per cercarle.

중괄호와 공백

129-319

커널은 K&R 형식을 따른다. 함수가 아닌 블록의 여는 중괄호는 제어문의 마지막에 두고, 닫는 중괄호는 그 블록을 시작한 문장과 같은 들여쓰기 열의 첫 위치에 둔다.

if (x is true) {
	we do y
}

switch (action) {
case KOBJ_ADD:
	return "add";
case KOBJ_REMOVE:
	return "remove";
case KOBJ_CHANGE:
	return "change";
default:
	return NULL;
}

함수 정의는 예외다. 함수의 여는 중괄호는 함수 이름 다음 줄의 첫 열에 둔다. 이 규칙은 K&R의 오랜 관례다.

int function(int x)
{
	body of function
}

닫는 중괄호는 보통 한 줄을 단독으로 차지한다. 단, 같은 제어 구문이 계속되는 do-while의 while이나 if문의 else는 닫는 중괄호와 같은 줄에 둔다.

do {
	body of do-loop
} while (condition);

if (x == y) {
	..
} else if (x > y) {
	...
} else {
	....
}

조건문이나 반복문 본문이 정말로 단순한 한 문장이면 중괄호를 생략할 수 있다. if와 else 가운데 어느 한쪽이 여러 문장이라 중괄호가 필요하다면 양쪽 모두에 중괄호를 사용한다. 반복문 안에 조건문처럼 하위 제어 흐름이 들어가면 바깥 반복문에도 중괄호를 사용해 범위를 분명히 한다.

if (condition)
	action();

if (condition)
	do_this();
else
	do_that();

if (condition) {
	do_this();
	do_that();
} else {
	otherwise();
}

while (condition) {
	if (test)
		do_something();
}

키워드 if, switch, case, for, do, while 뒤에는 공백을 둔다. 함수처럼 보이는 sizeof, typeof, alignof, __attribute__ 뒤에는 공백을 두지 않는다. 괄호 안쪽에는 공백을 넣지 않는다. 따라서 sizeof(struct file)은 맞고 sizeof( struct file )은 틀리다.

포인터 선언의 별표는 자료형이 아니라 변수명이나 함수명 쪽에 붙인다. char *linux_banner, char *match_strdup(...) 형식을 사용한다. =, +, -, <, >, *, /, %, |, &, ^, <=, >=, ==, !=, ?와 : 같은 이항·삼항 연산자 양쪽에는 공백을 둔다.

단항 &, *, +, -, ~, !와 sizeof, typeof, alignof, __attribute__, defined 뒤에는 공백을 두지 않는다. 전위·후위 ++와 -- 주위에도 공백을 두지 않으며, 구조체 멤버 연산자 .와 -> 주위에도 공백을 두지 않는다.

줄 끝 공백은 대부분의 편집기에서 보이지 않지만 패치를 불필요하게 오염시키고 이후 변경의 문맥 일치를 깨뜨린다. 일부 Git 설정은 자동으로 제거할 수 있으나, 이미 존재하는 줄 끝 공백을 기계적으로 모두 고치면 관련 없는 변경이 커질 수 있으므로 주의한다.

3) Posizionamento di parentesi graffe e spazi
---------------------------------------------

Un 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ì:

.. code-block:: c

	if (x is true) {
		we do y
	}

Questo è valido per tutte le espressioni che non siano funzioni (if, switch,
for, while, do).  Per esempio:

.. code-block:: c

	switch (action) {
	case KOBJ_ADD:
		return "add";
	case KOBJ_REMOVE:
		return "remove";
	case KOBJ_CHANGE:
		return "change";
	default:
		return NULL;
	}

Tuttavia, c'è il caso speciale, le funzioni: queste hanno la parentesi graffa
di apertura all'inizio della riga successiva, quindi:

.. code-block:: c

	int function(int x)
	{
		body of function
	}

Eretici 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).

Notate 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:

.. code-block:: c

	do {
		body of do-loop
	} while (condition);

e

.. code-block:: c

	if (x == y) {
		..
	} else if (x > y) {
		...
	} else {
		....
	}

Motivazione: K&R.

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.

Non usate inutilmente le graffe dove una singola espressione è sufficiente.

.. code-block:: c

	if (condition)
		action();

e

.. code-block:: c

	if (condition)
		do_this();
	else
		do_that();

Questo 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:

.. code-block:: c

	if (condition) {
		do_this();
		do_that();
	} else {
		otherwise();
	}

Inoltre, usate le graffe se un ciclo contiene più di una semplice istruzione:

.. code-block:: c

	while (condition) {
		if (test)
			do_something();
	}

3.1) Spazi
**********

Lo 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``).

Quindi utilizzate uno spazio dopo le seguenti parole chiave::

	if, switch, case, for, do, while

ma non con sizeof, typeof, alignof, o __attribute__.  Ad esempio,

.. code-block:: c


	s = sizeof(struct file);

Non aggiungete spazi attorno (dentro) ad un'espressione fra parentesi. Questo
esempio è **brutto**:

.. code-block:: c


	s = sizeof( struct file );

Quando dichiarate un puntatore ad una variabile o una funzione che ritorna un
puntatore, il posto suggerito per l'asterisco ``*`` è adiacente al nome della
variabile o della funzione, e non adiacente al nome del tipo. Esempi:

.. code-block:: c


	char *linux_banner;
	unsigned long long memparse(char *ptr, char **retptr);
	char *match_strdup(substring_t *s);

Usate uno spazio attorno (da ogni parte) alla maggior parte degli operatori
binari o ternari, come i seguenti::

	=  +  -  <  >  *  /  %  |  &  ^  <=  >=  ==  !=  ?  :

ma non mettete spazi dopo gli operatori unari::

	&  *  +  -  ~  !  sizeof  typeof  alignof  __attribute__  defined

nessuno spazio dopo l'operatore unario suffisso di incremento o decremento::

	++  --

nessuno spazio dopo l'operatore unario prefisso di incremento o decremento::

	++  --

e nessuno spazio attorno agli operatori dei membri di una struttura ``.`` e
``->``.

Non 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.

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.

이름 짓기

320-351

C는 이름을 짓는 언어다. 지역 변수는 짧고 용도가 즉시 드러나는 이름을 쓴다. 반복 횟수에는 i, 임시 값에는 tmp처럼 관례가 분명한 이름이 긴 CamelCase 이름보다 낫다. 혼합 대소문자 이름은 커널에서 권장하지 않는다.

반대로 전역 함수와 전역 변수는 무엇을 하는지 설명할 수 있는 이름이 필요하다. 전역 심볼 자체도 꼭 필요한 경우에만 만든다. 자료형을 이름에 반복하는 헝가리안 표기법은 컴파일러가 이미 알고 있는 정보를 중복하므로 사용하지 않는다.

새 코드에서는 master/slave와 blacklist/whitelist 용어를 피한다. 문맥에 따라 아래와 같이 역할을 실제로 설명하는 조합을 선택한다.

피할 표현권장 대안
master / slaveprimary 또는 main / secondary, replica 또는 subordinate
master / slaveinitiator 또는 requester / target 또는 responder
master / slavecontroller 또는 host / device, worker 또는 proxy
master / slaveleader / follower, director / performer
blacklist / whitelistdenylist / allowlist, blocklist / passlist

사용자 공간 ABI/API를 유지해야 하거나, 2020년 기준으로 이미 공개된 하드웨어·프로토콜 규격이 특정 용어를 의무화한 경우에는 예외가 될 수 있다. 이때도 새 내부 이름까지 무비판적으로 같은 표현으로 확장하지 않는다.

4) Assegnare nomi
-----------------

C è 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.

TUTTAVIA, 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.

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()``.

Codificare 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.

Le 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.

Se 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).

typedef 사용 기준

352-428

구조체나 포인터를 감추기 위해 typedef를 습관적으로 사용하지 않는다. vps_t a보다 struct virtual_container *a가 객체의 종류와 포인터 여부를 코드에 직접 드러낸다. 구조체 태그를 숨기면 선언만 보고 실제 자료 구조를 알기 어렵고, 포인터 typedef는 값과 참조의 차이까지 감춘다.

/* 피해야 할 형태 */
vps_t a;

/* 구조를 명시하는 형태 */
struct virtual_container *a;

typedef가 정당한 첫 번째 경우는 pte_t처럼 내용을 이식 가능한 방법으로 직접 해석할 수 없고 반드시 접근자 함수를 거쳐야 하는 완전히 불투명한 객체다. 그러나 불투명화와 접근자 함수 자체가 좋은 설계라는 뜻은 아니다. 페이지 테이블 엔트리는 아키텍처마다 표현이 달라 직접 접근할 공통 정보가 전혀 없기 때문에 예외가 성립한다.

두 번째는 int인지 long인지 혼동하기 쉬운 정수 표현을 추상화하는 경우다. 단순히 unsigned long에 myflags_t라는 새 이름을 붙이는 것은 이유가 없다. 설정에 따라 unsigned int와 unsigned long 사이에서 실제 표현이 달라져야 한다면 typedef가 그 차이를 격리할 수 있다.

typedef unsigned long myflags_t;

세 번째는 sparse가 정적 형 검사를 수행할 수 있도록 실제로 새로운 타입을 만드는 경우다. 네 번째는 u8, u16, u32, u64 및 부호 있는 대응형처럼 표준 C99 정수형과 동일하지만 Linux 코드에서 널리 쓰이는 타입이다. 새 코드에서 반드시 Linux 형을 써야 하는 것은 아니며, 기존 파일을 수정할 때는 그 코드가 이미 선택한 표기를 따른다.

다섯 번째는 사용자 공간과 공유되는 구조체다. 사용자 공간에 C99 타입 사용을 강제할 수 없고 커널 내부 u32를 그대로 노출할 수도 있으므로, UAPI 구조체에는 __u32 같은 타입을 사용한다. 이 예외들에 해당하지 않는다면 포인터나 직접 접근 가능한 구조체에 typedef를 만들지 않는다.

5) Definizione di tipi (typedef)
--------------------------------

Per favore non usate cose come ``vps_t``.
Usare il typedef per strutture e puntatori è uno **sbaglio**. Quando vedete:

.. code-block:: c

	vps_t a;

nei sorgenti, cosa significa?
Se, invece, dicesse:

.. code-block:: c

	struct virtual_container *a;

potreste dire cos'è effettivamente ``a``.

Molte persone pensano che la definizione dei tipi ``migliori la leggibilità``.
Non molto. Sono utili per:

 (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.

Magari 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.

In generale, un puntatore, o una struttura a cui si ha accesso diretto in
modo ragionevole, non dovrebbero **mai** essere definite con un typedef.

함수의 크기, 선언과 속성 순서

429-514

함수는 짧고 한 가지 작업만 수행해야 한다. 이상적인 함수는 80열 24행 화면 한두 개 안에서 전체를 볼 수 있다. 허용 가능한 길이는 복잡도와 들여쓰기 깊이에 반비례한다. 단순한 switch가 많은 case를 갖는 함수는 길어도 이해할 수 있지만, 중첩된 복잡한 함수는 더 짧아야 한다.

별도 이름으로 설명할 수 있는 복잡한 부분은 보조 함수로 분리한다. 컴파일러는 필요하면 이를 인라인으로 최적화할 수 있고, 사람이 읽고 검토하기도 쉬워진다. 지역 변수도 보통 5개에서 10개를 넘기지 않는 것이 좋다. 변수가 많다면 함수가 너무 많은 상태를 한꺼번에 다루고 있는지 살펴본다.

함수 사이에는 빈 줄 하나를 둔다. EXPORT_SYMBOL 계열 매크로는 함수의 닫는 중괄호 바로 다음 줄에 둔다. 함수 원형에는 인수 이름을 포함해야 하며, 함수 선언에 extern을 붙이지 않는다.

int system_is_up(void)
{
	return system_state == SYSTEM_RUNNING;
}
EXPORT_SYMBOL(system_is_up);

함수 선언 요소는 저장 클래스, 저장 클래스 속성, 반환형, 반환값 속성, 함수 이름, 이름을 포함한 매개변수, 매개변수 속성, 동작 속성 순으로 배치한다. 선언 예는 다음과 같다.

__init void * __must_check action(enum magic value, size_t size, u8 count,
				   char *fmt, ...) __printf(4, 5) __malloc;

저장 클래스에는 static과 extern이, 저장 클래스 속성에는 __init과 __cold가, 반환값 속성에는 __must_check가 해당한다. __printf 같은 매개변수 속성과 __malloc 같은 함수 동작 속성은 뒤쪽에 놓인다. 함수 정의에서는 컴파일러 제약 때문에 매개변수 속성을 저장 클래스 속성 다음으로 이동한다.

static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value,
		size_t size, u8 count, char *fmt, ...) __malloc
{
	...
}
6) Funzioni
-----------

Le 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.

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.

Comunque, 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).

Un'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.

Nei 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:

.. code-block:: c

	int system_is_up(void)
	{
		return system_state == SYSTEM_RUNNING;
	}
	EXPORT_SYMBOL(system_is_up);

6.1) Prototipi di funzione
**************************

Nei 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.

Non usate la parola chiave ``extern`` con le dichiarazioni di funzione perché
rende le righe più lunghe e non è strettamente necessario.

Quando scrivete i prototipi di funzione mantenete `l'ordine degli elementi <https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_.

Prendiamo questa dichiarazione di funzione come esempio::

 __init void * __must_check action(enum magic value, size_t size, u8 count,
                                  char *fmt, ...) __printf(4, 5) __malloc;

L'ordine suggerito per gli elementi di un prototipo di funzione è il seguente:

- classe d'archiviazione (in questo caso ``static __always_inline``. Da notare
  che ``__always_inline`` è tecnicamente un attributo ma che viene trattato come
  ``inline``)
- attributi della classe di archiviazione (in questo caso ``__init``, in altre
  parole la sezione, ma anche cose tipo ``__cold``)
- il tipo di ritorno (in questo caso, ``void *``)
- attributi per il valore di ritorno (in questo caso, ``__must_check``)
- il nome della funzione (in questo caso, ``action``)
- i 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)
- attributi dei parametri (in questo caso, ``__printf(4, 5)``)
- attributi per il comportamento della funzione (in questo caso, ``__malloc_``)

Notate che per la **definizione** di una funzione (il altre parole il corpo
della funzione), il compilatore non permette di usare gli attributi per i
parametri dopo i parametri. In questi casi, devono essere messi dopo gli
attributi della classe d'archiviazione (notate che la posizione di
``__printf(4,5)`` cambia rispetto alla **dichiarazione**)::

 static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value,
              size_t size, u8 count, char *fmt, ...) __malloc
 {
         ...
 }*)**``)**``)``)``*)``)``)``)``*``)``)``)*)

공통 종료 경로와 goto

515-587

goto는 무조건 피해야 하는 문법이 아니다. 함수 중간 여러 지점에서 동일한 자원을 정리해야 한다면 하나의 종료 경로로 모으는 것이 중복과 누락을 줄인다. 정리할 것이 없는 단순 오류라면 바로 return하는 편이 낫다.

레이블은 err1, err2처럼 위치만 나타내지 말고 out_free_buffer처럼 수행할 동작을 설명해야 한다. 공통 종료 경로는 본문 중첩을 줄이고, 정리 코드를 한곳에 모아 수정 시 한 경로만 고쳐도 되게 한다.

int fun(int a)
{
	int result = 0;
	char *buffer;

	buffer = kmalloc(SIZE, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	if (condition1) {
		while (loop1) {
			...
		}
		result = 1;
		goto out_free_buffer;
	}
	...
out_free_buffer:
	kfree(buffer);
	return result;
}

단일 err 레이블에서 foo->bar와 foo를 모두 해제하면 bar 할당 전에 실패한 경로도 초기화되지 않은 bar를 해제할 수 있다. 각 자원이 실제로 확보된 시점에 맞춰 레이블을 나누고, 아래쪽 정리 단계로 자연스럽게 떨어지게 해야 한다.

/* 잘못된 정리 경로 */
err:
	kfree(foo->bar);
	kfree(foo);
	return ret;

/* 할당 단계와 대응하는 정리 경로 */
err_free_bar:
	kfree(foo->bar);
err_free_foo:
	kfree(foo);
	return ret;

종료 경로가 맞는지는 각 할당과 초기화 단계에서 실패를 강제로 주입해 검증한다. 정상 경로만 실행해서는 이중 해제, 미할당 객체 해제, 참조 누수 같은 오류를 찾기 어렵다.

7) Centralizzare il ritorno delle funzioni
------------------------------------------

Sebbene sia deprecata da molte persone, l'istruzione goto è impiegata di
frequente dai compilatori sotto forma di salto incondizionato.

L'istruzione goto diventa utile quando una funzione ha punti d'uscita multipli
e vanno eseguite alcune procedure di pulizia in comune.  Se non è necessario
pulire alcunché, allora ritornate direttamente.

Assegnate un nome all'etichetta di modo che suggerisca cosa fa la goto o
perché esiste.  Un esempio di un buon nome potrebbe essere ``out_free_buffer:``
se la goto libera (free) un ``buffer``.  Evitate l'uso di nomi GW-BASIC come
``err1:`` ed ``err2:``, potreste doverli riordinare se aggiungete o rimuovete
punti d'uscita, e inoltre rende difficile verificarne la correttezza.

I motivo per usare le goto sono:

- i salti incondizionati sono più facili da capire e seguire
- l'annidamento si riduce
- si evita di dimenticare, per errore, di aggiornare un singolo punto d'uscita
- aiuta il compilatore ad ottimizzare il codice ridondante ;)

.. code-block:: c

	int fun(int a)
	{
		int result = 0;
		char *buffer;

		buffer = kmalloc(SIZE, GFP_KERNEL);
		if (!buffer)
			return -ENOMEM;

		if (condition1) {
			while (loop1) {
				...
			}
			result = 1;
			goto out_free_buffer;
		}
		...
	out_free_buffer:
		kfree(buffer);
		return result;
	}

Un baco abbastanza comune di cui bisogna prendere nota è il ``one err bugs``
che assomiglia a questo:

.. code-block:: c

	err:
		kfree(foo->bar);
		kfree(foo);
		return ret;

Il 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:``:

.. code-block:: c

	err_free_bar:
		kfree(foo->bar);
	err_free_foo:
		kfree(foo);
		return ret;

Idealmente, dovreste simulare condizioni d'errore per verificare i vostri
percorsi d'uscita.

주석

588-628

주석은 코드가 무엇을 하는지 그대로 읽어 주기보다 왜 그렇게 해야 하는지를 설명해야 한다. 복잡한 함수의 각 줄에 주석을 붙이는 대신 함수를 단순화하고, 함수 머리말에서 전체 목적과 제약을 설명한다.

외부에 공개되는 커널 API는 kernel-doc 형식을 사용한다. 코드만 반복하는 상투적인 주석은 피한다. 여러 줄 주석은 왼쪽에 별표 열을 두는 커널 형식을 일관되게 사용한다.

/*
 * 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.
 */

함수 내부의 동작뿐 아니라 중요한 자료 구조와 필드의 의미도 설명한다. 여러 변수를 한 선언에 묶으면 각 변수 옆에 의미를 적기 어려우므로, 주석이 필요한 데이터는 한 줄에 하나씩 선언한다.

8) Commenti
-----------

I 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.

Solitamente, 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É.

Per 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/ <it_doc_guide>` e in
``script/kernel-doc``.

Lo stile preferito per i commenti più lunghi (multi-riga) è:

.. code-block:: c

	/*
	 * 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.
	 */

È 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.

편집기와 자동 정렬 도구

629-723

일부 편집기의 기본 C 들여쓰기는 커널 형식과 맞지 않는다. 아래 Emacs 설정은 탭 기반 인수 정렬, 8자 기본 들여쓰기, case 레이블과 전처리기 매크로 정렬, 줄 끝 공백 표시 등을 Linux 소스 트리용 디렉터리 클래스에 적용하는 원문의 예다.

(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)

indent 도구를 쓴다면 -kr -i8 옵션 또는 scripts/Lindent를 사용할 수 있다. 다만 자동 정렬은 나쁜 프로그램 구조를 좋은 코드로 바꾸지 못한다. clang-format은 코드 재정렬, include 순서 정리, 변수 정렬, 텍스트 재배치와 같은 작업을 지원하며 관련 사용법은 Documentation/dev-tools/clang-format.rst에 있다. 여러 편집기에서 공통 설정을 읽게 하려면 EditorConfig도 사용할 수 있다.

9) Avete fatto un pasticcio
---------------------------

Va 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).

Quindi, 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:

.. code-block:: elisp

  (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)

Questo farà funzionare meglio emacs con lo stile del kernel per i file che
si trovano nella cartella ``~/src/linux-trees``.

Ma anche se doveste fallire nell'ottenere una formattazione sensata in emacs
non tutto è perduto: usate ``indent``.

Ora, 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.

``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.

Da 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 <it_clangformat>`.

Se 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/

Kconfig 파일

724-753

Kconfig의 config 아래 항목은 탭 한 단계로 들여쓰고, help 본문은 탭 다음에 공백 두 칸을 더 둔다. 다음 AUDIT 예제가 기준 형식을 보여 준다.

config 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.

데이터 손상처럼 위험한 동작을 허용하는 옵션의 프롬프트에는 DANGEROUS를 명시한다. 사용자는 메뉴만 보고도 위험을 알아야 한다.

config ADFS_FS_RW
	bool "ADFS write support (DANGEROUS)"
	depends on ADFS_FS
	...
10) File di configurazione Kconfig
----------------------------------

Per 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::

  config 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.

Le funzionalità davvero pericolose (per esempio il supporto alla scrittura
per certi filesystem) dovrebbero essere dichiarate chiaramente come tali
nella stringa di titolo::

  config ADFS_FS_RW
	bool "ADFS write support (DANGEROUS)"
	depends on ADFS_FS
	...

Per la documentazione completa sui file di configurazione, consultate
il documento Documentation/kbuild/kconfig-language.rst

자료 구조의 참조 수명

754-788

객체를 만들고 없애는 단일 스레드 문맥 밖에서도 찾을 수 있는 자료 구조라면 참조 계수가 필요하다. 다른 실행 주체가 객체를 발견할 수 있는데 수명 확보 절차가 없다면, 발견 직후 다른 CPU가 객체를 해제하는 use-after-free 경쟁이 생긴다.

잠금과 참조 계수는 서로 대체할 수 없다. 잠금은 객체 내용의 일관성을 보호하고, 참조 계수는 객체 메모리가 계속 존재하도록 보장한다. 객체를 잠그려면 먼저 그 객체를 안전하게 참조할 수 있어야 한다.

복잡한 객체는 두 단계 참조 계수를 사용할 수 있다. mm_struct의 mm_users는 주소 공간을 사용하는 사용자 수를, mm_count는 구조체 자체를 붙잡는 내부 참조를 센다. super_block의 s_count와 s_active도 외부 발견 가능성과 활성 사용을 서로 다른 계층에서 관리한다.

핵심 질문은 '다른 스레드가 이 객체를 어떻게 찾고, 찾은 순간부터 어떤 참조가 해제를 막는가'다. 이 질문에 답할 수 없다면 잠금이 있더라도 객체 수명 설계에는 결함이 있다.

11) Strutture dati
------------------

Le 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.

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.

Da 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.

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.

Un 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).

Ricordatevi: se un altro thread può trovare la vostra struttura dati, e non
avete un contatore di riferimenti per essa, quasi certamente avete un baco.

매크로, enum과 RTL

789-897

상수 매크로와 enum 레이블은 대문자로 쓴다. 서로 관련된 상수 집합은 enum으로 묶으면 컴파일러와 디버거가 의미를 더 잘 보존한다. 함수처럼 호출되는 매크로는 소문자 이름을 사용할 수 있지만, 형 검사와 디버깅이 가능한 static inline 함수를 우선한다.

#define CONSTANT 0x12345

여러 문장을 포함하는 매크로는 do { ... } while (0)로 감싼다. 이렇게 해야 호출자가 일반 함수처럼 뒤에 세미콜론을 붙일 수 있고, if-else 안에서도 하나의 문장으로 동작한다.

#define macrofun(a, b, c)			\
	do {					\
		if (a == 5)			\
			do_this(b, c);		\
	} while (0)

사용하지 않는 매개변수를 처리하려고 아무 일도 하지 않는 매크로를 만들기보다 빈 static inline 함수를 사용한다. 컴파일러는 인수의 타입을 검사하고 호출 코드를 제거한다. 아래처럼 인수를 void로 캐스팅하는 매크로는 가급적 피한다.

static inline void fun(struct foo *foo)
{
}

/* 가능하면 피하고 static inline 함수를 사용한다. */
#define macrofun(foo) do { (void) (foo); } while (0)

호출 함수에서 return이나 break를 실행하는 제어 흐름 매크로는 호출부만 읽어서는 흐름을 알 수 없으므로 피한다. 아래 FOO는 평범한 함수 호출처럼 보이지만 호출한 함수 전체에서 반환한다.

#define FOO(x)					\
	do {					\
		if (blah(x) < 0)		\
			return -EBUGGERED;	\
	} while (0)

매크로가 호출자 지역 변수에 몰래 의존해서도 안 된다. #define FOO(val) bar(index, val)처럼 index를 인수로 받지 않으면 호출부 문맥에 숨은 결합이 생긴다. 매크로 인수는 여러 번 평가될 수 있으므로 l-value로 사용하지 말고, 표현식과 각 인수는 연산자 우선순위가 바뀌지 않게 괄호로 감싼다.

#define FOO(val) bar(index, val)

#define CONSTANT 0x4000
#define CONSTEXP (CONSTANT | 3)

문장 표현식 매크로 내부의 임시 이름은 호출자 이름과 충돌할 수 있다. ret 대신 __foo_ret처럼 매크로에 고유한 접두사를 붙인다. 아래 원문 예제의 ret는 충돌 가능성을 보여 주기 위한 피해야 할 형태다.

#define FOO(x)			\
({					\
	typeof(x) ret;			\
	ret = calc_ret(x);		\
	(ret);				\
})

전처리기 세부 규칙은 GNU cpp 매뉴얼의 매크로 절을 참고한다. GCC 내부 표현인 RTL은 컴파일러 내부를 다루는 경우의 별도 주제이며, 커널 C 코드의 가독성을 위해 매크로로 복잡한 컴파일러 동작을 흉내 내서는 안 된다.

12) Macro, enumerati e RTL
---------------------------

I nomi delle macro che definiscono delle costanti e le etichette degli
enumerati sono scritte in maiuscolo.

.. code-block:: c

	#define CONSTANT 0x12345

Gli enumerati sono da preferire quando si definiscono molte costanti correlate.

I nomi delle macro in MAIUSCOLO sono preferibili ma le macro che assomigliano
a delle funzioni possono essere scritte in minuscolo.

Generalmente, le funzioni inline sono preferibili rispetto alle macro che
sembrano funzioni.

Le macro che contengono più istruzioni dovrebbero essere sempre chiuse in un
blocco do - while:

.. code-block:: c

	#define macrofun(a, b, c)			\
		do {					\
			if (a == 5)			\
				do_this(b, c);		\
		} while (0)

Le macro che sembrano funzioni con parametri non usati dovrebbero essere
sostituite da funzioni inline per evitare il problema.

.. code-block:: c

       static inline void fun(struct foo *foo)
       {
       }

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.

.. code-block:: c

       /*
        * Avoid doing this whenever possible and instead opt for static
        * inline functions
        */
       #define macrofun(foo) do { (void) (foo); } while (0)

Cose da evitare quando si usano le macro:

1) le macro che hanno effetti sul flusso del codice:

.. code-block:: c

	#define FOO(x)					\
		do {					\
			if (blah(x) < 0)		\
				return -EBUGGERED;	\
		} while (0)

sono **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.

2) le macro che dipendono dall'uso di una variabile locale con un nome magico:

.. code-block:: c

	#define FOO(val) bar(index, val)

potrebbe sembrare una bella cosa, ma è dannatamente confusionario quando uno
legge il codice e potrebbe romperlo con una cambiamento che sembra innocente.

3) le macro con argomenti che sono utilizzati come l-values; questo potrebbe
ritorcervisi contro se qualcuno, per esempio, trasforma FOO in una funzione
inline.

4) dimenticatevi delle precedenze: le macro che definiscono espressioni devono
essere racchiuse fra parentesi. State attenti a problemi simili con le macro
parametrizzate.

.. code-block:: c

	#define CONSTANT 0x4000
	#define CONSTEXP (CONSTANT | 3)

5) collisione nello spazio dei nomi quando si definisce una variabile locale in
una macro che sembra una funzione:

.. code-block:: c

	#define FOO(x)				\
	({					\
		typeof(x) ret;			\
		ret = calc_ret(x);		\
		(ret);				\
	})

ret è un nome comune per una variabile locale - __foo_ret difficilmente
andrà in conflitto con una variabile già esistente.

Il 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.

커널 메시지 출력

898-933

커널 메시지는 맞춤법을 지키고 짧고 분명하며 중의적이지 않게 쓴다. 문장 끝 마침표는 반드시 필요하지 않다. 여러 메시지를 구별하려고 괄호 안에 임의의 번호를 붙이는 방식은 사용자에게 의미가 없으므로 피한다.

장치와 연결된 메시지는 dev_err, dev_warn, dev_info처럼 장치 문맥을 자동으로 포함하는 함수를 사용한다. 장치가 없는 전역 문맥에서는 pr_notice, pr_info, pr_warn, pr_err 등을 사용한다.

드라이버는 정상 동작 중 조용해야 한다. 시스템에 잘못된 일이 생긴 것이 아니라 진단용 정보라면 dev_dbg 또는 pr_debug를 사용한다. 이 호출은 DEBUG가 정의되거나 CONFIG_DYNAMIC_DEBUG가 활성화된 경우가 아니면 컴파일 결과에서 제거된다. 더 상세한 로그에는 VERBOSE_DEBUG와 dev_vdbg를 사용할 수 있다.

Kconfig 디버그 옵션은 필요하면 -DDEBUG를 컴파일 옵션에 추가할 수 있고, 특정 파일에서만 #define DEBUG를 둘 수도 있다. 디버그 조건문 안에서 항상 출력해야 하는 메시지라면 printk(KERN_DEBUG ...)를 직접 사용할 수 있다.

13) Visualizzare i messaggi del kernel
--------------------------------------

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.

I messaggi del kernel non devono terminare con un punto fermo.

Scrivere i numeri fra parentesi (%d) non migliora alcunché e per questo
dovrebbero essere evitati.

Ci sono alcune macro per la diagnostica in <linux/dev_printk.h> 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, <linux/printk.h> 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.

Tirar 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().

Molti 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 ...).

메모리 할당

934-975

일반적인 커널 할당 함수에는 kmalloc, kzalloc, kmalloc_array, kcalloc, vmalloc, vzalloc이 있다. 각 함수의 주소 연속성, 초기화 여부와 수면 가능 문맥은 메모리 할당 문서를 함께 확인해야 한다.

구조체를 할당할 때는 자료형 이름을 반복하지 않고 포인터가 가리키는 객체의 크기를 사용한다. p = kmalloc(sizeof(*p), ...)는 선언 형식이 바뀌어도 할당 크기가 자동으로 따라가며, 긴 구조체 이름을 반복하지 않아 읽기 쉽다. kmalloc 반환값은 void 포인터이므로 캐스팅하지 않는다.

p = kmalloc(sizeof(*p), ...);

배열은 n * sizeof(...)를 직접 계산해 kmalloc에 넘기지 말고 kmalloc_array를 사용한다. 0으로 초기화된 배열은 kcalloc을 사용한다. 두 함수는 곱셈 오버플로를 검사하고 크기를 표현할 수 없으면 NULL을 반환한다.

p = kmalloc_array(n, sizeof(...), ...);

p = kcalloc(n, sizeof(...), ...);

__GFP_NOWARN 없이 일반 할당 함수를 호출하면 실패 시 할당기가 이미 스택 덤프를 출력한다. NULL을 받았다는 이유로 호출부에서 같은 실패 메시지를 추가하면 로그만 중복되므로 별도 오류 메시지를 출력할 필요가 없다.

14) Assegnare memoria
---------------------

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 <it_memory_allocation>`

Il modo preferito per passare la dimensione di una struttura è il seguente:

.. code-block:: c

	p = kmalloc(sizeof(*p), ...);

La 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.

Il 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.

Il modo preferito per assegnare un vettore è il seguente:

.. code-block:: c

	p = kmalloc_array(n, sizeof(...), ...);

Il modo preferito per assegnare un vettore a zero è il seguente:

.. code-block:: c

	p = kcalloc(n, sizeof(...), ...);

Entrambe verificano la condizione di overflow per la dimensione
d'assegnamento n * sizeof(...), se accade ritorneranno NULL.

Questi 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.

inline의 과도한 사용

976-997

inline은 함수를 자동으로 빠르게 만드는 마법의 옵션이 아니다. 매크로를 타입 안전한 함수로 바꾸는 경우처럼 적절한 용도가 있지만, 남용하면 같은 함수 본문이 여러 호출 지점에 복제되어 커널 이미지가 커진다.

커진 코드는 CPU 명령 캐시 점유를 늘리고 page cache에 쓸 수 있는 메모리를 줄여 시스템 전체를 느리게 할 수 있다. 원문은 page cache miss로 디스크 탐색이 발생하면 약 5ms가 걸릴 수 있고, 그 시간에는 매우 많은 CPU 사이클이 들어간다는 예로 코드 크기 비용을 설명한다.

경험칙으로 코드가 세 줄보다 긴 함수에는 inline을 붙이지 않는다. 단, 매개변수가 컴파일 시간 상수이고 그 값 때문에 함수 대부분이 제거된다는 것을 확실히 아는 경우는 예외다. kmalloc() 인라인 함수가 대표적인 예다.

static 함수가 한 번만 호출되므로 inline이 항상 이득이라는 주장도 유지보수 관점에서는 충분하지 않다. GCC는 이런 함수를 스스로 인라인할 수 있다. 나중에 두 번째 호출자가 생겼을 때 inline을 제거해야 하는 부담이, 컴파일러가 이미 할 최적화를 강제하는 작은 이득보다 크다.

15) Il morbo inline
-------------------

Sembra 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.

Spesso 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.

함수 이름과 반환값

998-1034

성공과 실패를 나타내는 반환값은 주로 두 형식이다. 오류 코드 정수는 음수 -Exxx가 실패이고 0이 성공이다. 성공 여부를 나타내는 불리언은 0이 실패이고 0이 아닌 값이 성공이다. 두 규약을 뒤섞으면 조건식을 반대로 해석하는 찾기 어려운 버그가 생긴다.

함수 이름이 동작이나 명령형이면 오류 코드 정수를 반환한다. 함수 이름이 어떤 조건을 묻는 술어라면 성공 여부를 나타내는 bool을 반환한다.

add_work()는 '작업을 추가하라'는 명령이므로 성공 시 0, 실패 시 -EBUSY를 반환한다. pci_dev_present()는 '일치하는 PCI 장치가 존재하는가'라는 술어이므로 찾으면 1, 찾지 못하면 0을 반환한다.

EXPORT된 함수와 모든 공개 함수는 이 규약을 따라야 한다. private static 함수에도 같은 규칙을 적용하는 것을 권장한다. 계산 자체의 결과를 반환하는 함수는 이 규칙의 대상이 아니며, 포인터 함수가 NULL 또는 ERR_PTR로 실패를 표현하듯 정상 범위를 벗어난 값으로 오류를 나타낼 수 있다.

16) Nomi e valori di ritorno delle funzioni
-------------------------------------------

Le 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).

Mischiare 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::

	Se 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"

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.

Tutte 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.

Le 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.

bool 사용

1035-1067

Linux 커널의 bool은 C99 _Bool의 별칭이다. bool 값은 0 또는 1로만 평가되며, bool로 변환하면 자동으로 false 또는 true가 된다. 따라서 bool 값에 !!를 다시 적용할 필요가 없고, 값에는 숫자 1과 0 대신 true와 false를 사용한다.

함수 반환형과 스택 지역 변수에는 의미가 맞으면 bool을 자유롭게 사용할 수 있다. 참과 거짓을 저장하는 int보다 의도를 분명히 하므로 권장된다.

그러나 bool의 크기와 정렬은 대상 아키텍처에 따라 달라질 수 있다. 캐시 라인 배치나 구조체 크기가 중요한 자료 구조에는 bool을 사용하지 않는다. 참·거짓 필드가 많다면 1비트 bitfield로 모으거나 u8 같은 고정 폭 타입을 고려한다.

함수 인수에 true/false가 여러 개 나열되면 호출부만 보고 각 값의 뜻을 알기 어렵다. 이 경우 하나의 비트 flags 인수로 묶으면 더 읽기 쉬울 수 있다. 그 밖의 제한적인 구조체 필드와 인수에서는 bool이 가독성을 높인다.

17) L'uso di bool
-----------------

Nel 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.

Quando si usano i valori booleani, dovreste utilizzare le definizioni di true
e false al posto dei valori 1 e 0.

Per 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.

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.

Se 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.

Come 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.

Detto ciò, un uso parsimonioso di bool nelle strutture dati e negli argomenti
può migliorare la leggibilità.

기존 커널 매크로 재사용

1068-1091

include/linux/kernel.h에는 흔한 계산을 안전하고 일관되게 수행하는 매크로가 이미 있다. 배열 원소 수를 직접 sizeof 식으로 다시 만들지 말고 ARRAY_SIZE를 사용한다.

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

구조체 특정 멤버의 크기는 sizeof_field를 사용한다. 엄격한 타입 검사를 수행하는 min과 max도 제공된다. 비슷한 매크로를 새로 쓰기 전에 기존 헤더에 같은 기능이 있는지 확인한다.

#define sizeof_field(t, f) (sizeof(((t*)0)->f))
18) Non reinventate le macro del kernel
---------------------------------------

Il 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:

.. code-block:: c

	#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

Analogamente, se dovete calcolare la dimensione di un qualche campo di una
struttura, usate

.. code-block:: c

	#define sizeof_field(t, f) (sizeof(((t*)0)->f))

Ci 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.

소스 파일의 editor modeline 금지

1092-1125

Emacs와 Vim을 비롯한 편집기는 소스 파일 안의 특별한 표식을 읽어 모드, 들여쓰기와 빌드 명령을 바꿀 수 있다. 원문은 다음 세 형태를 예로 든다.

-*- mode: c -*-

/*
Local Variables:
compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"
End:
*/

/* vim:set sw=8 noet */

이런 modeline을 커널 소스에 넣지 않는다. 개발자는 각자 편집기 설정과 사용자 정의 모드를 가지고 있으며, 저장소의 소스 파일이 개인 환경을 덮어써서는 안 된다. 들여쓰기와 모드 설정을 위한 표식도 모두 이 금지 대상이다.

19) Linee di configurazione degli editor e altre schifezze
-----------------------------------------------------------

Alcuni 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:

.. code-block:: c

	-*- mode: c -*-

O come queste:

.. code-block:: c

	/*
	Local Variables:
	compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"
	End:
	*/

Vim interpreta i marcatori come questi:

.. code-block:: c

	/* vim:set sw=8 noet */

Non 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.

인라인 어셈블리

1126-1158

아키텍처 전용 코드에서 CPU 또는 플랫폼 기능과 연결하려면 인라인 어셈블리가 필요할 수 있다. 필요한 경우에는 사용하되, C로 같은 작업을 할 수 있다면 불필요한 어셈블리를 쓰지 않는다. 가능한 하드웨어 접근도 C 접근자와 헬퍼로 표현한다.

반복되는 짧은 어셈블리 조각은 C 매개변수를 받는 단순한 헬퍼 함수로 감싼다. 크고 복잡한 어셈블리 함수는 .S 파일에 두고 C 헤더에 대응하는 원형을 선언한다. 어셈블리로 구현한 함수의 C 원형에는 asmlinkage를 사용한다.

GCC가 부수 효과를 알아채지 못해 asm 문을 제거할 가능성이 있을 때는 volatile이 필요할 수 있다. 그러나 모든 asm에 기계적으로 volatile을 붙이면 컴파일러 최적화를 제한하므로 실제 필요성을 판단해야 한다.

하나의 asm 문에 여러 명령을 쓸 때는 명령마다 별도 문자열 줄을 사용하고, 마지막을 제외한 각 문자열을 \n\t로 끝낸다. 그러면 생성된 어셈블리에서도 다음 명령이 올바르게 줄 바꿈되고 들여쓰기된다.

asm ("magic %reg1, #42\n\t"
     "more_magic %reg2, %reg3"
     : /* outputs */ : /* inputs */ : /* clobbers */);
20) Inline assembly
-------------------

Nel 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.

Considerate 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.

Il 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``.

Potreste 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.

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:

.. code-block:: c

	asm ("magic %reg1, #42\n\t"
	     "more_magic %reg2, %reg3"
	     : /* outputs */ : /* inputs */ : /* clobbers */);

조건부 컴파일

1159-1208

가능하면 .c 파일 안에 #if와 #ifdef를 두지 않는다. 전처리 조건은 코드를 읽기 어렵게 하고 C의 제어 흐름을 끊는다. 대신 헤더에서 설정이 켜졌을 때의 실제 함수와 꺼졌을 때의 no-op stub을 각각 정의하고, .c 파일은 함수를 무조건 호출하게 한다. 컴파일러는 빈 stub 호출을 제거하므로 실행 결과와 비용은 동일하다.

함수 일부나 표현식 일부를 조건부로 지우기보다 함수 전체를 컴파일 대상에서 제외한다. 표현식 중간에 ifdef가 필요하다면 해당 부분을 보조 함수로 분리하고 그 함수 정의에 조건을 적용한다.

특정 설정에서만 사용되지 않을 수 있는 함수나 변수는 전처리 조건으로 선언 자체를 감싸기보다 __maybe_unused로 표시할 수 있다. 모든 설정에서 항상 사용되지 않는 코드라면 표시로 숨기지 말고 삭제한다.

코드 안에서는 가능한 경우 IS_ENABLED로 Kconfig 심볼을 C 불리언 식으로 바꾸어 일반 if문에 사용한다.

if (IS_ENABLED(CONFIG_SOMETHING)) {
	...
}

컴파일러는 상수 조건을 접어 설정에 맞는 블록만 남기므로 런타임 오버헤드가 없다. 동시에 C 컴파일러가 블록 내부의 문법, 타입과 심볼 참조를 검사할 수 있다. 단, 설정이 꺼지면 존재하지 않는 심볼을 블록 안에서 참조하는 경우에는 여전히 #ifdef가 필요하다.

몇 줄을 넘는 #if 또는 #ifdef 블록의 끝에는 #endif와 같은 줄에 원래 조건을 주석으로 적는다.

#ifdef CONFIG_SOMETHING
...
#endif /* CONFIG_SOMETHING */
21) Compilazione sotto condizione
---------------------------------

Ovunque 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.

È 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.

Se 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).

Nel codice, dov'è possibile, usate la macro IS_ENABLED per convertire i
simboli Kconfig in espressioni booleane C, e quindi usatela nelle classiche
condizioni C:

.. code-block:: c

	if (IS_ENABLED(CONFIG_SOMETHING)) {
		...
	}

Il 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.

Alla 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:

.. code-block:: c

	#ifdef CONFIG_SOMETHING
	...
	#endif /* CONFIG_SOMETHING */

참고 문헌

1209-1230

원문은 C 언어와 프로그래밍 관례를 위한 기본 참고 문헌으로 Brian W. Kernighan과 Dennis M. Ritchie의 The C Programming Language 2판, Brian W. Kernighan과 Rob Pike의 The Practice of Programming을 제시한다.

K&R 및 이 문서와 충돌하지 않는 범위에서 cpp, gcc, GCC internals와 indent의 GNU 매뉴얼도 참고한다. C 언어 국제 표준화 작업 그룹 WG14와 Greg Kroah-Hartman의 OLS 2002 Kernel CodingStyle 발표 자료가 함께 열거되어 있다.

Appendice I) riferimenti
------------------------

The 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).

The Practice of Programming
by Brian W. Kernighan and Rob Pike.
Addison-Wesley, Inc., 1999.
ISBN 0-201-61586-X.

Manuali 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/

WG14 è il gruppo internazionale di standardizzazione per il linguaggio C,
URL: https://www.open-std.org/JTC1/SC22/WG14/

Kernel CodingStyle, by [email protected] at OLS 2002:
http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/