198348577SFederico Vaga.. SPDX-License-Identifier: GPL-2.0
298348577SFederico Vaga
398348577SFederico Vaga.. include:: ../disclaimer-ita.rst
498348577SFederico Vaga
598348577SFederico Vaga:Original: :ref:`Documentation/process/deprecated.rst <deprecated>`
698348577SFederico Vaga:Translator: Federico Vaga <federico.vaga@vaga.pv.it>
798348577SFederico Vaga
898348577SFederico Vaga.. _it_deprecated:
998348577SFederico Vaga
1098348577SFederico Vaga==============================================================================
1198348577SFederico VagaInterfacce deprecate, caratteristiche del linguaggio, attributi, e convenzioni
1298348577SFederico Vaga==============================================================================
1398348577SFederico Vaga
1498348577SFederico VagaIn un mondo perfetto, sarebbe possibile prendere tutti gli usi di
1598348577SFederico Vagaun'interfaccia deprecata e convertirli in quella nuova, e così sarebbe
1698348577SFederico Vagapossibile rimuovere la vecchia interfaccia in un singolo ciclo di sviluppo.
1798348577SFederico VagaTuttavia, per via delle dimensioni del kernel, la gerarchia dei manutentori e
1898348577SFederico Vagale tempistiche, non è sempre possibile fare questo tipo di conversione tutta
1998348577SFederico Vagain una volta. Questo significa che nuove istanze di una vecchia interfaccia
2098348577SFederico Vagapotrebbero aggiungersi al kernel proprio quando si sta cercando di rimuoverle,
2198348577SFederico Vagaaumentando così il carico di lavoro. Al fine di istruire gli sviluppatori su
2298348577SFederico Vagacosa è considerato deprecato (e perché), è stata create la seguente lista a cui
2398348577SFederico Vagafare riferimento quando qualcuno propone modifiche che usano cose deprecate.
2498348577SFederico Vaga
2598348577SFederico Vaga__deprecated
2698348577SFederico Vaga------------
2798348577SFederico VagaNonostante questo attributo marchi visibilmente un interfaccia come deprecata,
2898348577SFederico Vaga`non produce più alcun avviso durante la compilazione
2998348577SFederico Vaga<https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_
3098348577SFederico Vagaperché uno degli obiettivi del kernel è quello di compilare senza avvisi;
3198348577SFederico Vagainoltre, nessuno stava agendo per rimuovere queste interfacce. Nonostante l'uso
3298348577SFederico Vagadi `__deprecated` in un file d'intestazione sia opportuno per segnare una
3398348577SFederico Vagainterfaccia come 'vecchia', questa non è una soluzione completa. L'interfaccia
3498348577SFederico Vagadeve essere rimossa dal kernel, o aggiunta a questo documento per scoraggiarne
3598348577SFederico Vagal'uso.
3698348577SFederico Vaga
37b67aa4efSFederico VagaBUG() e BUG_ON()
38b67aa4efSFederico Vaga----------------
39b67aa4efSFederico VagaAl loro posto usate WARN() e WARN_ON() per gestire le
40b67aa4efSFederico Vagacondizioni "impossibili" e gestitele come se fosse possibile farlo.
41b67aa4efSFederico VagaNonostante le funzioni della famiglia BUG() siano state progettate
42b67aa4efSFederico Vagaper asserire "situazioni impossibili" e interrompere in sicurezza un
43b67aa4efSFederico Vagathread del kernel, queste si sono rivelate essere troppo rischiose
44b67aa4efSFederico Vaga(per esempio, in quale ordine rilasciare i *lock*? Ci sono stati che
45b67aa4efSFederico Vagasono stati ripristinati?). Molto spesso l'uso di BUG()
46b67aa4efSFederico Vagadestabilizza il sistema o lo corrompe del tutto, il che rende
47b67aa4efSFederico Vagaimpossibile un'attività di debug o anche solo leggere un rapporto
48b67aa4efSFederico Vagacirca l'errore.  Linus ha un'opinione molto critica al riguardo:
49b67aa4efSFederico Vaga`email 1
50b67aa4efSFederico Vaga<https://lore.kernel.org/lkml/CA+55aFy6jNLsywVYdGp83AMrXBo_P-pkjkphPGrO=82SPKCpLQ@mail.gmail.com/>`_,
51b67aa4efSFederico Vaga`email 2
52b67aa4efSFederico Vaga<https://lore.kernel.org/lkml/CAHk-=whDHsbK3HTOpTF=ue_o04onRwTEaK_ZoJp_fjbqq4+=Jw@mail.gmail.com/>`_
53b67aa4efSFederico Vaga
54b67aa4efSFederico VagaTenete presente che la famiglia di funzioni WARN() dovrebbe essere
55b67aa4efSFederico Vagausato solo per situazioni che si suppone siano "impossibili".  Se
56b67aa4efSFederico Vagavolete avvisare gli utenti riguardo a qualcosa di possibile anche se
57b67aa4efSFederico Vagaindesiderato, usare le funzioni della famiglia pr_warn().  Chi
58b67aa4efSFederico Vagaamministra il sistema potrebbe aver attivato l'opzione sysctl
59b67aa4efSFederico Vaga*panic_on_warn* per essere sicuri che il sistema smetta di funzionare
60b67aa4efSFederico Vagain caso si verifichino delle condizioni "inaspettate". (per esempio,
61b67aa4efSFederico Vagadate un'occhiata al questo `commit
62b67aa4efSFederico Vaga<https://git.kernel.org/linus/d4689846881d160a4d12a514e991a740bcb5d65a>`_)
63b67aa4efSFederico Vaga
6498348577SFederico VagaCalcoli codificati negli argomenti di un allocatore
6598348577SFederico Vaga----------------------------------------------------
6698348577SFederico VagaIl calcolo dinamico delle dimensioni (specialmente le moltiplicazioni) non
6798348577SFederico Vagadovrebbero essere fatto negli argomenti di funzioni di allocazione di memoria
6898348577SFederico Vaga(o simili) per via del rischio di overflow. Questo può portare a valori più
6998348577SFederico Vagapiccoli di quelli che il chiamante si aspettava. L'uso di questo modo di
7098348577SFederico Vagaallocare può portare ad un overflow della memoria di heap e altri
7198348577SFederico Vagamalfunzionamenti. (Si fa eccezione per valori numerici per i quali il
72da1d9cafSFederico Vagacompilatore può generare avvisi circa un potenziale overflow. Tuttavia, anche in
73da1d9cafSFederico Vagaquesti casi è preferibile riscrivere il codice come suggerito di seguito).
7498348577SFederico Vaga
7598348577SFederico VagaPer esempio, non usate ``count * size`` come argomento::
7698348577SFederico Vaga
7798348577SFederico Vaga	foo = kmalloc(count * size, GFP_KERNEL);
7898348577SFederico Vaga
7998348577SFederico VagaAl suo posto, si dovrebbe usare l'allocatore a due argomenti::
8098348577SFederico Vaga
8198348577SFederico Vaga	foo = kmalloc_array(count, size, GFP_KERNEL);
8298348577SFederico Vaga
83da1d9cafSFederico VagaNello specifico, kmalloc() può essere sostituta da kmalloc_array(), e kzalloc()
84da1d9cafSFederico Vagada kcalloc().
85da1d9cafSFederico Vaga
8698348577SFederico VagaSe questo tipo di allocatore non è disponibile, allora dovrebbero essere usate
8798348577SFederico Vagale funzioni del tipo *saturate-on-overflow*::
8898348577SFederico Vaga
8998348577SFederico Vaga	bar = vmalloc(array_size(count, size));
9098348577SFederico Vaga
9198348577SFederico VagaUn altro tipico caso da evitare è quello di calcolare la dimensione di una
9298348577SFederico Vagastruttura seguita da un vettore di altre strutture, come nel seguente caso::
9398348577SFederico Vaga
9498348577SFederico Vaga	header = kzalloc(sizeof(*header) + count * sizeof(*header->item),
9598348577SFederico Vaga			 GFP_KERNEL);
9698348577SFederico Vaga
9798348577SFederico VagaInvece, usate la seguente funzione::
9898348577SFederico Vaga
9998348577SFederico Vaga	header = kzalloc(struct_size(header, item, count), GFP_KERNEL);
10098348577SFederico Vaga
101ac771142SFederico Vaga.. note:: Se per caso state usando struct_size() su una struttura dati che
102ac771142SFederico Vaga	  in coda contiene un array di lunghezza zero o uno, allora siete
103ac771142SFederico Vaga	  invitati a riorganizzare il vostro codice usando il
104ac771142SFederico Vaga	  `flexible array member <#zero-length-and-one-element-arrays>`_.
105ac771142SFederico Vaga
106da1d9cafSFederico VagaPer altri calcoli, usate le funzioni size_mul(), size_add(), e size_sub(). Per
107da1d9cafSFederico Vagaesempio, al posto di::
108da1d9cafSFederico Vaga
109da1d9cafSFederico Vaga       foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL);
110da1d9cafSFederico Vaga
111da1d9cafSFederico Vagadovreste scrivere:
112da1d9cafSFederico Vaga
113da1d9cafSFederico Vaga       foo = krealloc(size_add(current_size,
114da1d9cafSFederico Vaga                               size_mul(chunk_size,
115da1d9cafSFederico Vaga                                        size_sub(count, 3))), GFP_KERNEL);
116da1d9cafSFederico Vaga
117da1d9cafSFederico VagaPer maggiori dettagli fate riferimento a array3_size() e flex_array_size(), ma
118da1d9cafSFederico Vagaanche le funzioni della famiglia check_mul_overflow(), check_add_overflow(),
119da1d9cafSFederico Vagacheck_sub_overflow(), e check_shl_overflow().
12098348577SFederico Vaga
12198348577SFederico Vagasimple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
12298348577SFederico Vaga----------------------------------------------------------------------
123b67aa4efSFederico VagaLe funzioni simple_strtol(), simple_strtoll(),
124b67aa4efSFederico Vagasimple_strtoul(), e simple_strtoull() ignorano volutamente
12598348577SFederico Vagai possibili overflow, e questo può portare il chiamante a generare risultati
126b67aa4efSFederico Vagainaspettati. Le rispettive funzioni kstrtol(), kstrtoll(),
127b67aa4efSFederico Vagakstrtoul(), e kstrtoull() sono da considerarsi le corrette
12898348577SFederico Vagasostitute; tuttavia va notato che queste richiedono che la stringa sia
12998348577SFederico Vagaterminata con il carattere NUL o quello di nuova riga.
13098348577SFederico Vaga
13198348577SFederico Vagastrcpy()
13298348577SFederico Vaga--------
133b67aa4efSFederico VagaLa funzione strcpy() non fa controlli agli estremi del buffer
13498348577SFederico Vagadi destinazione. Questo può portare ad un overflow oltre i limiti del
13598348577SFederico Vagabuffer e generare svariati tipi di malfunzionamenti. Nonostante l'opzione
13698348577SFederico Vaga`CONFIG_FORTIFY_SOURCE=y` e svariate opzioni del compilatore aiutano
13798348577SFederico Vagaa ridurne il rischio, non c'è alcuna buona ragione per continuare ad usare
138ac771142SFederico Vagaquesta funzione. La versione sicura da usare è strscpy(), tuttavia va
139ac771142SFederico Vagaprestata attenzione a tutti quei casi dove viene usato il valore di
140ac771142SFederico Vagaritorno di strcpy().  La funzione strscpy() non ritorna un puntatore
141ac771142SFederico Vagaalla destinazione, ma un contatore dei byte non NUL copiati (oppure
142ac771142SFederico Vagaun errno negativo se la stringa è stata troncata).
14398348577SFederico Vaga
14498348577SFederico Vagastrncpy() su stringe terminate con NUL
14598348577SFederico Vaga--------------------------------------
146b67aa4efSFederico VagaL'utilizzo di strncpy() non fornisce alcuna garanzia sul fatto che
14798348577SFederico Vagail buffer di destinazione verrà terminato con il carattere NUL. Questo
14898348577SFederico Vagapotrebbe portare a diversi overflow di lettura o altri malfunzionamenti
14998348577SFederico Vagacausati, appunto, dalla mancanza del terminatore. Questa estende la
15098348577SFederico Vagaterminazione nel buffer di destinazione quando la stringa d'origine è più
15198348577SFederico Vagacorta; questo potrebbe portare ad una penalizzazione delle prestazioni per
15298348577SFederico Vagachi usa solo stringe terminate. La versione sicura da usare è
153ac771142SFederico Vagastrscpy(), tuttavia va prestata attenzione a tutti quei casi dove
154ac771142SFederico Vagaviene usato il valore di ritorno di strncpy().  La funzione strscpy()
155ac771142SFederico Vaganon ritorna un puntatore alla destinazione, ma un contatore dei byte
156ac771142SFederico Vaganon NUL copiati (oppure un errno negativo se la stringa è stata
157ac771142SFederico Vagatroncata). Tutti i casi che necessitano di estendere la
158ac771142SFederico Vagaterminazione con NUL dovrebbero usare strscpy_pad().
15998348577SFederico Vaga
160053f8fc7SKees CookSe il chiamate no usa stringhe terminate con NUL, allore strncpy()
16198348577SFederico Vagapuò continuare ad essere usata, ma i buffer di destinazione devono essere
16298348577SFederico Vagamarchiati con l'attributo `__nonstring <https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_
16398348577SFederico Vagaper evitare avvisi durante la compilazione.
16498348577SFederico Vaga
16598348577SFederico Vagastrlcpy()
16698348577SFederico Vaga---------
167b67aa4efSFederico VagaLa funzione strlcpy(), per prima cosa, legge interamente il buffer di
16898348577SFederico Vagaorigine, magari leggendo più di quanto verrà effettivamente copiato. Questo
16998348577SFederico Vagaè inefficiente e può portare a overflow di lettura quando la stringa non è
170ac771142SFederico Vagaterminata con NUL. La versione sicura da usare è strscpy(), tuttavia
171ac771142SFederico Vagava prestata attenzione a tutti quei casi dove viene usato il valore di
172ac771142SFederico Vagaritorno di strlcpy(), dato che strscpy() ritorna un valore di errno
173ac771142SFederico Vaganegativo quanto la stringa viene troncata.
174b67aa4efSFederico Vaga
175b67aa4efSFederico VagaSegnaposto %p nella stringa di formato
176b67aa4efSFederico Vaga--------------------------------------
177b67aa4efSFederico Vaga
178b67aa4efSFederico VagaTradizionalmente, l'uso del segnaposto "%p" nella stringa di formato
179b67aa4efSFederico Vagaesponne un indirizzo di memoria in dmesg, proc, sysfs, eccetera.  Per
180b67aa4efSFederico Vagaevitare che questi indirizzi vengano sfruttati da malintenzionati,
181b67aa4efSFederico Vagatutto gli usi di "%p" nel kernel rappresentano l'hash dell'indirizzo,
182b67aa4efSFederico Vagarendendolo di fatto inutilizzabile.  Nuovi usi di "%p" non dovrebbero
183b67aa4efSFederico Vagaessere aggiunti al kernel.  Per una rappresentazione testuale di un
184b67aa4efSFederico Vagaindirizzo usate "%pS", l'output è migliore perché mostrerà il nome del
185b67aa4efSFederico Vagasimbolo.  Per tutto il resto, semplicemente non usate "%p".
186b67aa4efSFederico Vaga
187b67aa4efSFederico VagaParafrasando la `guida
188b67aa4efSFederico Vaga<https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_
189b67aa4efSFederico Vagadi Linus:
190b67aa4efSFederico Vaga
191b67aa4efSFederico Vaga- Se il valore hash di "%p" è inutile, chiediti se il puntatore stesso
192b67aa4efSFederico Vaga  è importante. Forse dovrebbe essere rimosso del tutto?
193b67aa4efSFederico Vaga- Se credi davvero che il vero valore del puntatore sia importante,
194b67aa4efSFederico Vaga  perché alcuni stati del sistema o i livelli di privilegi di un
195b67aa4efSFederico Vaga  utente sono considerati "special"? Se pensi di poterlo giustificare
196b67aa4efSFederico Vaga  (in un commento e nel messaggio del commit) abbastanza bene da
197b67aa4efSFederico Vaga  affrontare il giudizio di Linus, allora forse potrai usare "%px",
198b67aa4efSFederico Vaga  assicurandosi anche di averne il permesso.
199b67aa4efSFederico Vaga
200191cf329SFederico VagaPotete disabilitare temporaneamente l'hashing di "%p" nel caso in cui questa
201191cf329SFederico Vagafunzionalità vi sia d'ostacolo durante una sessione di debug. Per farlo
202191cf329SFederico Vagaaggiungete l'opzione di debug "`no_hash_pointers
203191cf329SFederico Vaga<https://git.kernel.org/linus/5ead723a20e0447bc7db33dc3070b420e5f80aa6>`_" alla
204191cf329SFederico Vagariga di comando del kernel.
20598348577SFederico Vaga
20698348577SFederico VagaVettori a dimensione variabile (VLA)
20798348577SFederico Vaga------------------------------------
20898348577SFederico Vaga
20998348577SFederico VagaUsare VLA sullo stack produce codice molto peggiore rispetto a quando si usano
21098348577SFederico Vagavettori a dimensione fissa. Questi `problemi di prestazioni <https://git.kernel.org/linus/02361bc77888>`_,
21198348577SFederico Vagatutt'altro che banali, sono già un motivo valido per eliminare i VLA; in
21298348577SFederico Vagaaggiunta sono anche un problema per la sicurezza. La crescita dinamica di un
21398348577SFederico Vagavettore nello stack potrebbe eccedere la memoria rimanente in tale segmento.
21498348577SFederico VagaQuesto può portare a dei malfunzionamenti, potrebbe sovrascrivere
21598348577SFederico Vagadati importanti alla fine dello stack (quando il kernel è compilato senza
21698348577SFederico Vaga`CONFIG_THREAD_INFO_IN_TASK=y`), o sovrascrivere un pezzo di memoria adiacente
21798348577SFederico Vagaallo stack (quando il kernel è compilato senza `CONFIG_VMAP_STACK=y`).
218b67aa4efSFederico Vaga
219b67aa4efSFederico VagaSalto implicito nell'istruzione switch-case
220b67aa4efSFederico Vaga-------------------------------------------
221b67aa4efSFederico Vaga
222b67aa4efSFederico VagaIl linguaggio C permette ai casi di un'istruzione `switch` di saltare al
223b67aa4efSFederico Vagaprossimo caso quando l'istruzione "break" viene omessa alla fine del caso
224b67aa4efSFederico Vagacorrente. Tuttavia questo rende il codice ambiguo perché non è sempre ovvio se
225b67aa4efSFederico Vagal'istruzione "break" viene omessa intenzionalmente o è un baco. Per esempio,
226b67aa4efSFederico Vagaosservando il seguente pezzo di codice non è chiaro se lo stato
227b67aa4efSFederico Vaga`STATE_ONE` è stato progettato apposta per eseguire anche `STATE_TWO`::
228b67aa4efSFederico Vaga
229b67aa4efSFederico Vaga  switch (value) {
230b67aa4efSFederico Vaga  case STATE_ONE:
231b67aa4efSFederico Vaga          do_something();
232b67aa4efSFederico Vaga  case STATE_TWO:
233b67aa4efSFederico Vaga          do_other();
234b67aa4efSFederico Vaga          break;
235b67aa4efSFederico Vaga  default:
236b67aa4efSFederico Vaga          WARN("unknown state");
237b67aa4efSFederico Vaga  }
238b67aa4efSFederico Vaga
239b67aa4efSFederico VagaDato che c'è stata una lunga lista di problemi `dovuti alla mancanza dell'istruzione
240b67aa4efSFederico Vaga"break" <https://cwe.mitre.org/data/definitions/484.html>`_, oggigiorno non
241b67aa4efSFederico Vagapermettiamo più che vi sia un "salto implicito" (*fall-through*). Per
242b67aa4efSFederico Vagaidentificare un salto implicito intenzionale abbiamo adottato la pseudo
243b67aa4efSFederico Vagaparola chiave 'fallthrough' che viene espansa nell'estensione di gcc
244b67aa4efSFederico Vaga`__attribute__((fallthrough))` `Statement Attributes
245b67aa4efSFederico Vaga<https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_.
246b67aa4efSFederico Vaga(Quando la sintassi C17/C18 `[[fallthrough]]` sarà più comunemente
247b67aa4efSFederico Vagasupportata dai compilatori C, analizzatori statici, e dagli IDE,
248b67aa4efSFederico Vagaallora potremo usare quella sintassi per la pseudo parola chiave)
249b67aa4efSFederico Vaga
250b67aa4efSFederico VagaQuando la sintassi [[fallthrough]] sarà più comunemente supportata dai
251b67aa4efSFederico Vagacompilatori, analizzatori statici, e ambienti di sviluppo IDE,
252b67aa4efSFederico Vagaallora potremo usarla anche noi.
253b67aa4efSFederico Vaga
254b67aa4efSFederico VagaNe consegue che tutti i blocchi switch/case devono finire in uno dei seguenti
255b67aa4efSFederico Vagamodi:
256b67aa4efSFederico Vaga
257b67aa4efSFederico Vaga* ``break;``
258b67aa4efSFederico Vaga* `fallthrough;``
259b67aa4efSFederico Vaga* ``continue;``
260b67aa4efSFederico Vaga* ``goto <label>;``
261b67aa4efSFederico Vaga* ``return [expression];``
262ac771142SFederico Vaga
263ac771142SFederico VagaArray di lunghezza zero o con un solo elemento
264ac771142SFederico Vaga----------------------------------------------
265ac771142SFederico VagaAll'interno del kernel ricorre spesso la necessita di avere membri
266ac771142SFederico Vagadi dimensione variabile all'interno di una struttura dati. In questi
267ac771142SFederico Vagacasi il codice del kernel dovrebbe usare sempre i `"flexible array
268ac771142SFederico Vagamember" <https://en.wikipedia.org/wiki/Flexible_array_member>`_. La
269ac771142SFederico Vagatecnica degli array a lunghezza nulla o di un solo elemento non
270ac771142SFederico Vagadovrebbe essere più usata.
271ac771142SFederico Vaga
272ac771142SFederico VagaNel codice C più vecchio, la dichiarazione di un membro di dimensione
273ac771142SFederico Vagavariabile in coda ad una struttura dati veniva fatto dichiarando un
274ac771142SFederico Vagaarray di un solo elemento posizionato alla fine della struttura dati::
275ac771142SFederico Vaga
276ac771142SFederico Vaga        struct something {
277ac771142SFederico Vaga                size_t count;
278ac771142SFederico Vaga                struct foo items[1];
279ac771142SFederico Vaga        };
280ac771142SFederico Vaga
281ac771142SFederico VagaQuesto ha portato ad un calcolo di sizeof() traballante (dovrebbe
282ac771142SFederico Vagarimuovere la dimensione del singolo elemento in coda per calcolare la
283ac771142SFederico Vagadimensione esatta dell' "intestazione"). Per evitare questi problemi è
284ac771142SFederico Vagastata introdotta un' `estensione a GNU C
285ac771142SFederico Vaga<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ che
286ac771142SFederico Vagapermettesse la dichiarazione di array a lungezza zero::
287ac771142SFederico Vaga
288ac771142SFederico Vaga        struct something {
289ac771142SFederico Vaga                size_t count;
290ac771142SFederico Vaga                struct foo items[0];
291ac771142SFederico Vaga        };
292ac771142SFederico Vaga
293ac771142SFederico VagaMa questo ha portato nuovi problemi, e non ha risolto alcuni dei
294ac771142SFederico Vagaproblemi che affliggono entrambe le tecniche: per esempio
295ac771142SFederico Vagal'impossibilità di riconoscere se un array di quel tipo viene usato
296ac771142SFederico Vaganel mezzo di una struttura dati e _non_ alla fine (potrebbe accadere
297ac771142SFederico Vagasia direttamente, sia indirettamente quando si usano le unioni o le
298ac771142SFederico Vagastrutture di strutture).
299ac771142SFederico Vaga
300ac771142SFederico VagaLo standard C99 introduce i "flexible array members". Questi array non
301ac771142SFederico Vagahanno una dimensione nella loro dichiarazione::
302ac771142SFederico Vaga
303ac771142SFederico Vaga        struct something {
304ac771142SFederico Vaga                size_t count;
305ac771142SFederico Vaga                struct foo items[];
306ac771142SFederico Vaga        };
307ac771142SFederico Vaga
308ac771142SFederico VagaQuesto è il modo con cui ci si aspetta che vengano dichiarati gli
309ac771142SFederico Vagaelementi di lunghezza variabile in coda alle strutture dati.  Permette
310ac771142SFederico Vagaal compilatore di produrre errori quando gli array flessibili non si
311ac771142SFederico Vagatrovano alla fine della struttura dati, il che permette di prevenire
312ac771142SFederico Vagaalcuni tipi di bachi dovuti a `comportamenti inaspettati
313ac771142SFederico Vaga<https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_.
314ac771142SFederico VagaInoltre, permette al compilatore di analizzare correttamente le
315ac771142SFederico Vagadimensioni degli array (attraverso sizeof(), `CONFIG_FORTIFY_SOURCE`,
316ac771142SFederico Vagae `CONFIG_UBSAN_BOUNDS`). Per esempio, non esiste alcun meccanismo in
317ac771142SFederico Vagagrado di avvisarci che il seguente uso di sizeof() dia sempre come
318ac771142SFederico Vagazero come risultato::
319ac771142SFederico Vaga
320ac771142SFederico Vaga        struct something {
321ac771142SFederico Vaga                size_t count;
322ac771142SFederico Vaga                struct foo items[0];
323ac771142SFederico Vaga        };
324ac771142SFederico Vaga
325ac771142SFederico Vaga        struct something *instance;
326ac771142SFederico Vaga
327ac771142SFederico Vaga        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
328ac771142SFederico Vaga        instance->count = count;
329ac771142SFederico Vaga
330ac771142SFederico Vaga        size = sizeof(instance->items) * instance->count;
331ac771142SFederico Vaga        memcpy(instance->items, source, size);
332ac771142SFederico Vaga
333ac771142SFederico VagaIl valore di ``size`` nell'ultima riga sarà ``zero``, quando uno
334ac771142SFederico Vagainvece si aspetterebbe che il suo valore sia la dimensione totale in
335c1f8e848SFederico Vagabyte dell'allocazione dinamica che abbiamo appena fatto per l'array
336ac771142SFederico Vaga``items``. Qui un paio di esempi reali del problema: `collegamento 1
337ac771142SFederico Vaga<https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_,
338ac771142SFederico Vaga`collegamento 2
339ac771142SFederico Vaga<https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_.
340ac771142SFederico VagaInvece, `i flexible array members hanno un tipo incompleto, e quindi
341ac771142SFederico Vagasizeof() non può essere applicato
342ac771142SFederico Vaga<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_; dunque ogni
343ac771142SFederico Vagauso scorretto di questo operatore verrà identificato immediatamente
344ac771142SFederico Vagadurante la compilazione.
345ac771142SFederico Vaga
346ac771142SFederico VagaPer quanto riguarda gli array di un solo elemento, bisogna essere
347ac771142SFederico Vagaconsapevoli che `questi array occupano almeno quanto lo spazio di un
348ac771142SFederico Vagasingolo oggetti dello stesso tipo
349ac771142SFederico Vaga<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_, e quindi
350ac771142SFederico Vagacontribuiscono al calcolo della dimensione della struttura che li
351ac771142SFederico Vagacontiene. In questo caso è facile commettere errori quando si vuole
352ac771142SFederico Vagacalcolare la dimensione totale della memoria totale da allocare per
353ac771142SFederico Vagauna struttura dati::
354ac771142SFederico Vaga
355ac771142SFederico Vaga        struct something {
356ac771142SFederico Vaga                size_t count;
357ac771142SFederico Vaga                struct foo items[1];
358ac771142SFederico Vaga        };
359ac771142SFederico Vaga
360ac771142SFederico Vaga        struct something *instance;
361ac771142SFederico Vaga
362ac771142SFederico Vaga        instance = kmalloc(struct_size(instance, items, count - 1), GFP_KERNEL);
363ac771142SFederico Vaga        instance->count = count;
364ac771142SFederico Vaga
365ac771142SFederico Vaga        size = sizeof(instance->items) * instance->count;
366ac771142SFederico Vaga        memcpy(instance->items, source, size);
367ac771142SFederico Vaga
368ac771142SFederico VagaIn questo esempio ci siamo dovuti ricordare di usare ``count - 1`` in
369ac771142SFederico Vagastruct_size(), altrimenti avremmo --inavvertitamente-- allocato
370ac771142SFederico Vagamemoria per un oggetti ``items`` in più. Il modo più pulito e meno
371ac771142SFederico Vagapropenso agli errori è quello di usare i `flexible array member`, in
372ac771142SFederico Vagacombinazione con struct_size() e flex_array_size()::
373ac771142SFederico Vaga
374ac771142SFederico Vaga        struct something {
375ac771142SFederico Vaga                size_t count;
376ac771142SFederico Vaga                struct foo items[];
377ac771142SFederico Vaga        };
378ac771142SFederico Vaga
379ac771142SFederico Vaga        struct something *instance;
380ac771142SFederico Vaga
381ac771142SFederico Vaga        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
382ac771142SFederico Vaga        instance->count = count;
383ac771142SFederico Vaga
384ac771142SFederico Vaga        memcpy(instance->items, source, flex_array_size(instance, items, instance->count));
385c1f8e848SFederico Vaga
386c1f8e848SFederico VagaCi sono due casi speciali dove è necessario usare la macro DECLARE_FLEX_ARRAY()
387c1f8e848SFederico Vaga(da notare che la stessa macro è chiamata __DECLARE_FLEX_ARRAY() nei file di
388c1f8e848SFederico Vagaintestazione UAPI). Uno è quando l'array flessibile è l'unico elemento di una
389*3ee23096SFabio Fantonistruttura, e l'altro quando è parte di un unione. Per motivi non tecnici, entrambi
390c1f8e848SFederico Vagai casi d'uso non sono permessi dalla specifica C99. Per esempio, per
391c1f8e848SFederico Vagaconvertire il seguente codice::
392c1f8e848SFederico Vaga
393c1f8e848SFederico Vaga    struct something {
394c1f8e848SFederico Vaga        ...
395c1f8e848SFederico Vaga        union {
396c1f8e848SFederico Vaga            struct type1 one[0];
397c1f8e848SFederico Vaga            struct type2 two[0];
398c1f8e848SFederico Vaga        };
399c1f8e848SFederico Vaga    };
400c1f8e848SFederico Vaga
401c1f8e848SFederico VagaLa macro di supporto dev'essere usata::
402c1f8e848SFederico Vaga
403c1f8e848SFederico Vaga    struct something {
404c1f8e848SFederico Vaga        ...
405c1f8e848SFederico Vaga        union {
406c1f8e848SFederico Vaga            DECLARE_FLEX_ARRAY(struct type1, one);
407c1f8e848SFederico Vaga            DECLARE_FLEX_ARRAY(struct type2, two);
408c1f8e848SFederico Vaga        };
409c1f8e848SFederico Vaga    };
410