162306a36Sopenharmony_ci.. include:: ../disclaimer-sp.rst
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci:Original: :ref:`Documentation/process/deprecated.rst <deprecated>`
462306a36Sopenharmony_ci:Translator: Sergio Gonzalez <sergio.collado@gmail.com>
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci.. _sp_deprecated:
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci============================================================================
962306a36Sopenharmony_ciInterfaces obsoletos, Características del lenguaje, Atributos y Convenciones
1062306a36Sopenharmony_ci============================================================================
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ciEn un mundo perfecto, sería posible convertir todas las instancias de
1362306a36Sopenharmony_cialguna API obsoleta en una nueva API y quitar la API anterior en un
1462306a36Sopenharmony_ciúnico ciclo de desarrollo. Desafortunadamente, debido al tamaño del kernel,
1562306a36Sopenharmony_cila jerarquía de mantenimiento, y el tiempo, no siempre es posible hacer
1662306a36Sopenharmony_ciestos cambios de una única vez. Esto significa que las nuevas instancias
1762306a36Sopenharmony_cihan de ir creándose en el kernel, mientras que las antiguas se quitan,
1862306a36Sopenharmony_cihaciendo que la cantidad de trabajo para limpiar las APIs crezca. Para
1962306a36Sopenharmony_ciinformar a los desarrolladores sobre qué ha sido declarado obsoleto y por
2062306a36Sopenharmony_ciqué, ha sido creada esta lista como un lugar donde indicar cuando los usos
2162306a36Sopenharmony_ciobsoletos son propuestos para incluir en el kernel.
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci__deprecated
2462306a36Sopenharmony_ci------------
2562306a36Sopenharmony_ciMientras que este atributo señala visualmente que un interface ha sido
2662306a36Sopenharmony_cideclarado obsoleto, este `no produce más avisos durante las compilaciones
2762306a36Sopenharmony_ci<https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_
2862306a36Sopenharmony_ciporque uno de los objetivos del kernel es que compile sin avisos, y
2962306a36Sopenharmony_cinadie ha hecho nada para quitar estos interfaces obsoletos. Mientras
3062306a36Sopenharmony_cique usar `__deprecated` es sencillo para anotar una API obsoleta en
3162306a36Sopenharmony_ciun archivo de cabecera, no es la solución completa. Dichos interfaces
3262306a36Sopenharmony_cideben o bien ser quitados por completo, o añadidos a este archivo para
3362306a36Sopenharmony_cidesanimar a otros a usarla en el futuro.
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ciBUG() y BUG_ON()
3662306a36Sopenharmony_ci----------------
3762306a36Sopenharmony_ciUse WARN() y WARN_ON() en su lugar, y gestione las condiciones de error
3862306a36Sopenharmony_ci"imposibles" tan elegantemente como se pueda. Mientras que la familia de
3962306a36Sopenharmony_cifunciones BUG() fueron originalmente diseñadas para actuar como una
4062306a36Sopenharmony_ci"situación imposible", confirmar y disponer de un hilo del kernel de forma
4162306a36Sopenharmony_ci"segura", estas funciones han resultado ser demasiado arriesgadas. (e.g.
4262306a36Sopenharmony_ci"¿en qué orden se necesitan liberar los locks? ¿Se han restaurado sus
4362306a36Sopenharmony_ciestados?). La popular función BUG() desestabilizará el sistema o lo romperá
4462306a36Sopenharmony_citotalmente, lo cual hace imposible depurarlo o incluso generar reportes de
4562306a36Sopenharmony_cicrash. Linus tiene una `opinión muy fuerte
4662306a36Sopenharmony_ci<https://lore.kernel.org/lkml/CA+55aFy6jNLsywVYdGp83AMrXBo_P-pkjkphPGrO=82SPKCpLQ@mail.gmail.com/>`_
4762306a36Sopenharmony_ciy sentimientos `sobre esto
4862306a36Sopenharmony_ci<https://lore.kernel.org/lkml/CAHk-=whDHsbK3HTOpTF=ue_o04onRwTEaK_ZoJp_fjbqq4+=Jw@mail.gmail.com/>`_.
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciNótese que la familia de funciones WARN() únicamente debería ser usada
5162306a36Sopenharmony_cien situaciones que se "esperan no sean alcanzables". Si se quiere
5262306a36Sopenharmony_ciavisar sobre situaciones "alcanzables pero no deseadas", úsese la familia
5362306a36Sopenharmony_cide funciones pr_warn(). Los responsables del sistema pueden haber definido
5462306a36Sopenharmony_ci*panic_on_warn* sysctl para asegurarse que sus sistemas no continúan
5562306a36Sopenharmony_ciejecutándose en presencia del condiciones "no alcanzables". (Por ejemplo,
5662306a36Sopenharmony_civéase commits como `este
5762306a36Sopenharmony_ci<https://git.kernel.org/linus/d4689846881d160a4d12a514e991a740bcb5d65a>`_.)
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ciOperaciones aritméticas en los argumentos de reserva de memoria
6062306a36Sopenharmony_ci---------------------------------------------------------------
6162306a36Sopenharmony_ciLos cálculos dinámicos de tamaño (especialmente multiplicaciones) no
6262306a36Sopenharmony_cideberían realizarse en los argumentos de reserva de memoria (o similares)
6362306a36Sopenharmony_cidebido al riesgo de desbordamiento. Esto puede llevar a valores rotando y
6462306a36Sopenharmony_cique se realicen reservas de memoria menores que las que se esperaban. El
6562306a36Sopenharmony_ciuso de esas reservas puede llevar a desbordamientos en el 'heap' de memoria
6662306a36Sopenharmony_ciy otros funcionamientos incorrectos. (Una excepción a esto son los valores
6762306a36Sopenharmony_ciliterales donde el compilador si puede avisar si estos puede desbordarse.
6862306a36Sopenharmony_ciDe todos modos, el método recomendado en estos caso es reescribir el código
6962306a36Sopenharmony_cicomo se sugiere a continuación para evitar las operaciones aritméticas en
7062306a36Sopenharmony_cila reserva de memoria.)
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ciPor ejemplo, no utilice `count * size`` como argumento, como en::
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci    foo = kmalloc(count * size, GFP_KERNEL);
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ciEn vez de eso, utilice la reserva con dos argumentos::
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci    	foo = kmalloc_array(count, size, GFP_KERNEL);
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciEspecíficamente, kmalloc() puede ser sustituido con kmalloc_array(),
8162306a36Sopenharmony_cikzalloc() puede ser sustituido con kcalloc().
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ciSi no existen funciones con dos argumentos, utilice las funciones que se
8462306a36Sopenharmony_cisaturan, en caso de desbordamiento::
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci    	bar = vmalloc(array_size(count, size));
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ciOtro caso común a evitar es calcular el tamaño de una estructura com
8962306a36Sopenharmony_cila suma de otras estructuras, como en::
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci    header = kzalloc(sizeof(*header) + count * sizeof(*header->item),
9262306a36Sopenharmony_ci   		  GFP_KERNEL);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ciEn vez de eso emplee::
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci    header = kzalloc(struct_size(header, item, count), GFP_KERNEL);
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci.. note:: Si se usa struct_size() en una estructura que contiene un elemento
9962306a36Sopenharmony_ci    	de longitud cero o un array de un único elemento como un array miembro,
10062306a36Sopenharmony_ci    	por favor reescribir ese uso y cambiar a un `miembro array flexible
10162306a36Sopenharmony_ci    	<#zero-length-and-one-element-arrays>`_
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ciPara otros cálculos, por favor use las funciones de ayuda: size_mul(),
10562306a36Sopenharmony_cisize_add(), and size_sub(). Por ejemplo, en el caso de::
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci    foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL);
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ciRe-escríbase, como::
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci    foo = krealloc(size_add(current_size,
11262306a36Sopenharmony_ci   			 size_mul(chunk_size,
11362306a36Sopenharmony_ci   				  size_sub(count, 3))), GFP_KERNEL);
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ciPara más detalles, mire también array3_size() y flex_array_size(),
11662306a36Sopenharmony_cicomo también la familia de funciones relacionadas check_mul_overflow(),
11762306a36Sopenharmony_cicheck_add_overflow(), check_sub_overflow(), y check_shl_overflow().
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_cisimple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
12162306a36Sopenharmony_ci----------------------------------------------------------------------
12262306a36Sopenharmony_ciLas funciones: simple_strtol(), simple_strtoll(), simple_strtoul(), y
12362306a36Sopenharmony_cisimple_strtoull() explícitamente ignoran los desbordamientos, lo que puede
12462306a36Sopenharmony_cillevar a resultados inesperados por las funciones que las llaman. Las
12562306a36Sopenharmony_cifunciones respectivas kstrtol(), kstrtoll(), kstrtoul(), y kstrtoull()
12662306a36Sopenharmony_citienden a ser reemplazos correctos, aunque nótese que necesitarán que la
12762306a36Sopenharmony_cicadena de caracteres termine en NUL o en el carácter de línea nueva.
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_cistrcpy()
13162306a36Sopenharmony_ci--------
13262306a36Sopenharmony_cistrcpy() no realiza verificaciones de los límites del buffer de destino.
13362306a36Sopenharmony_ciEsto puede resultar en desbordamientos lineals más allá del fin del buffer,
13462306a36Sopenharmony_cicausando todo tipo de errores. Mientras `CONFIG_FORTIFY_SOURCE=y` otras
13562306a36Sopenharmony_civarias opciones de compilación reducen el riesgo de usar esta función, no
13662306a36Sopenharmony_cihay ninguna buena razón para añadir nuevos usos de esta. El remplazo seguro
13762306a36Sopenharmony_cies la función strscpy(), aunque se ha de tener cuidado con cualquier caso
13862306a36Sopenharmony_cien el el valor retornado por strcpy() sea usado, ya que strscpy() no
13962306a36Sopenharmony_cidevuelve un puntero a el destino, sino el número de caracteres no nulos
14062306a36Sopenharmony_cicompilados (o el valor negativo de errno cuando se trunca la cadena de
14162306a36Sopenharmony_cicaracteres).
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cistrncpy() en cadenas de caracteres terminadas en NUL
14462306a36Sopenharmony_ci----------------------------------------------------
14562306a36Sopenharmony_ciEl uso de strncpy() no garantiza que el buffer de destino esté terminado en
14662306a36Sopenharmony_ciNUL. Esto puede causar varios errores de desbordamiento en lectura y otros
14762306a36Sopenharmony_citipos de funcionamiento erróneo debido a que falta la terminación en NUL.
14862306a36Sopenharmony_ciEsta función también termina la cadena de caracteres en NUL en el buffer de
14962306a36Sopenharmony_cidestino si la cadena de origen es más corta que el buffer de destino, lo
15062306a36Sopenharmony_cicual puede ser una penalización innecesaria para funciones usen esta
15162306a36Sopenharmony_cifunción con cadenas de caracteres que sí están terminadas en NUL.
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ciCuando se necesita que la cadena de destino sea terminada en NUL,
15462306a36Sopenharmony_ciel mejor reemplazo es usar la función strscpy(), aunque se ha de tener
15562306a36Sopenharmony_cicuidado en los casos en los que el valor de strncpy() fuera usado, ya que
15662306a36Sopenharmony_cistrscpy() no devuelve un puntero al destino, sino el número de
15762306a36Sopenharmony_cicaracteres no nulos copiados (o el valor negativo de errno cuando se trunca
15862306a36Sopenharmony_cila cadena de caracteres). Cualquier caso restante que necesitase todavía
15962306a36Sopenharmony_ciser terminado en el caracter nulo, debería usar strscpy_pad().
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ciSi una función usa cadenas de caracteres que no necesitan terminar en NUL,
16262306a36Sopenharmony_cidebería usarse strtomem(), y el destino debería señalarse con el atributo
16362306a36Sopenharmony_ci`__nonstring
16462306a36Sopenharmony_ci<https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_
16562306a36Sopenharmony_cipara evitar avisos futuros en el compilador. Para casos que todavía
16662306a36Sopenharmony_cinecesitan cadenas de caracteres que se rellenen al final con el
16762306a36Sopenharmony_cicaracter NUL, usar strtomem_pad().
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_cistrlcpy()
17062306a36Sopenharmony_ci---------
17162306a36Sopenharmony_cistrlcpy() primero lee por completo el buffer de origen (ya que el valor
17262306a36Sopenharmony_cidevuelto intenta ser el mismo que el de strlen()). Esta lectura puede
17362306a36Sopenharmony_cisobrepasar el límite de tamaño del destino. Esto ineficiente y puede causar
17462306a36Sopenharmony_cidesbordamientos de lectura si la cadena de origen no está terminada en el
17562306a36Sopenharmony_cicarácter NUL. El reemplazo seguro de esta función es strscpy(), pero se ha
17662306a36Sopenharmony_cide tener cuidado que en los casos en lso que se usase el valor devuelto de
17762306a36Sopenharmony_cistrlcpy(), ya que strscpy() devolverá valores negativos de erno cuando se
17862306a36Sopenharmony_ciproduzcan truncados.
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ciEspecificación de formato %p
18162306a36Sopenharmony_ci----------------------------
18262306a36Sopenharmony_ciTradicionalmente,el uso de "%p" en el formato de cadenas de caracteres
18362306a36Sopenharmony_ciresultaría en exponer esas direcciones en dmesg, proc, sysfs, etc. En vez
18462306a36Sopenharmony_cide dejar que sean una vulnerabilidad, todos los "%p" que se usan en el
18562306a36Sopenharmony_cikernel se imprimen como un hash, haciéndolos efectivamente inutilizables
18662306a36Sopenharmony_cipara usarlos como direcciones de memoria. Nuevos usos de "%p" no deberían
18762306a36Sopenharmony_ciser añadidos al kernel. Para textos de direcciones, usar "%pS" es
18862306a36Sopenharmony_cimejor, ya que resulta en el nombre del símbolo. Para prácticamente el
18962306a36Sopenharmony_ciresto de casos, mejor no usar "%p" en absoluto.
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ciParafraseando las actuales `direcciones de Linus <https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_:
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci- Si el valor "hasheado" "%p" no tienen ninguna finalidad, preguntarse si el
19462306a36Sopenharmony_ci  puntero es realmente importante. ¿Quizás se podría quitar totalmente?
19562306a36Sopenharmony_ci- Si realmente se piensa que el valor del puntero es importante, ¿porqué
19662306a36Sopenharmony_ci  algún estado del sistema o nivel de privilegio de usuario es considerado
19762306a36Sopenharmony_ci  "especial"? Si piensa que puede justificarse (en comentarios y mensajes
19862306a36Sopenharmony_ci  del commit), de forma suficiente como para pasar el escrutinio de Linux,
19962306a36Sopenharmony_ci  quizás pueda usar el "%p", a la vez que se asegura que tiene los permisos
20062306a36Sopenharmony_ci  correspondientes.
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ciSi está depurando algo donde el "%p" hasheado está causando problemas,
20362306a36Sopenharmony_cise puede arrancar temporalmente con la opción de depuración "`no_hash_pointers
20462306a36Sopenharmony_ci<https://git.kernel.org/linus/5ead723a20e0447bc7db33dc3070b420e5f80aa6>`_".
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ciArrays de longitud variable (VLAs)
20862306a36Sopenharmony_ci----------------------------------
20962306a36Sopenharmony_ciUsando VLA en la pila (stack) produce un código mucho peor que los arrays
21062306a36Sopenharmony_cide tamaño estático. Mientras que estos errores no triviales de `rendimiento
21162306a36Sopenharmony_ci<https://git.kernel.org/linus/02361bc77888>`_  son razón suficiente
21262306a36Sopenharmony_cipara no usar VLAs, esto además son un riesgo de seguridad. El crecimiento
21362306a36Sopenharmony_cidinámico del array en la pila, puede exceder la memoria restante en
21462306a36Sopenharmony_ciel segmento de la pila. Esto podría llevara a un fallo, posible sobre-escritura
21562306a36Sopenharmony_cide contenido al final de la pila (cuando se construye sin
21662306a36Sopenharmony_ci`CONFIG_THREAD_INFO_IN_TASK=y`), o sobre-escritura de la memoria adyacente
21762306a36Sopenharmony_cia la pila (cuando se construye sin `CONFIG_VMAP_STACK=y`).
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ciSwitch case fall-through implícito
22162306a36Sopenharmony_ci----------------------------------
22262306a36Sopenharmony_ciEl lenguaje C permite a las sentencias 'switch' saltar de un caso al
22362306a36Sopenharmony_cisiguiente caso cuando la sentencia de ruptura "break" no aparece al final
22462306a36Sopenharmony_cidel caso. Esto, introduce ambigüedad en el código, ya que no siempre está
22562306a36Sopenharmony_ciclaro si el 'break' que falta es intencionado o un olvido. Por ejemplo, no
22662306a36Sopenharmony_cies obvio solamente mirando al código si `STATE_ONE` está escrito para
22762306a36Sopenharmony_ciintencionadamente saltar en `STATE_TWO`::
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci    switch (value) {
23062306a36Sopenharmony_ci    case STATE_ONE:
23162306a36Sopenharmony_ci   	 do_something();
23262306a36Sopenharmony_ci    case STATE_TWO:
23362306a36Sopenharmony_ci   	 do_other();
23462306a36Sopenharmony_ci   	 break;
23562306a36Sopenharmony_ci    default:
23662306a36Sopenharmony_ci   	 WARN("unknown state");
23762306a36Sopenharmony_ci    }
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ciYa que ha habido una larga lista de defectos `debidos a declaraciones de "break"
24062306a36Sopenharmony_cique faltan <https://cwe.mitre.org/data/definitions/484.html>`_, no se
24162306a36Sopenharmony_cipermiten 'fall-through' implícitos. Para identificar 'fall-through'
24262306a36Sopenharmony_ciintencionados, se ha adoptado la pseudo-palabra-clave macro "falltrhrough",
24362306a36Sopenharmony_cique expande las extensiones de gcc `__attribute__((__fallthrough__))
24462306a36Sopenharmony_ci<https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_.
24562306a36Sopenharmony_ci(Cuando la sintaxis de C17/c18 `[[fallthrough]]` sea más comúnmente
24662306a36Sopenharmony_cisoportadas por los compiladores de C, analizadores estáticos, e IDEs,
24762306a36Sopenharmony_cise puede cambiar a usar esa sintaxis para esa pseudo-palabra-clave.
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ciTodos los bloques switch/case deben acabar en uno de:
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci* break;
25262306a36Sopenharmony_ci* fallthrough;
25362306a36Sopenharmony_ci* continue;
25462306a36Sopenharmony_ci* goto <label>;
25562306a36Sopenharmony_ci* return [expression];
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ciArrays de longitud cero y un elemento
25962306a36Sopenharmony_ci-------------------------------------
26062306a36Sopenharmony_ciHay una necesidad habitual en el kernel de proveer una forma para declarar
26162306a36Sopenharmony_ciun grupo de elementos consecutivos de tamaño dinámico en una estructura.
26262306a36Sopenharmony_ciEl código del kernel debería usar siempre `"miembros array flexible" <https://en.wikipedia.org/wiki/Flexible_array_member>`_
26362306a36Sopenharmony_cien estos casos. El estilo anterior de arrays de un elemento o de longitud
26462306a36Sopenharmony_cicero, no deben usarse más.
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ciEn el código C más antiguo, los elementos finales de tamaño dinámico se
26762306a36Sopenharmony_ciobtenían especificando un array de un elemento al final de una estructura::
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci    	struct something {
27062306a36Sopenharmony_ci            	size_t count;
27162306a36Sopenharmony_ci            	struct foo items[1];
27262306a36Sopenharmony_ci    	};
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ciEn código C más antiguo, elementos seguidos de tamaño dinámico eran creados
27562306a36Sopenharmony_ciespecificando una array de un único elemento al final de una estructura::
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci    	struct something {
27862306a36Sopenharmony_ci            	size_t count;
27962306a36Sopenharmony_ci            	struct foo items[1];
28062306a36Sopenharmony_ci    	};
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ciEsto llevó a resultados incorrectos en los cálculos de tamaño mediante
28362306a36Sopenharmony_cisizeof() (el cual hubiera necesitado eliminar el tamaño del último elemento
28462306a36Sopenharmony_cipara tener un tamaño correcto de la "cabecera"). Una `extensión de GNU C
28562306a36Sopenharmony_ci<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ se empezó a usar
28662306a36Sopenharmony_cipara permitir los arrays de longitud cero, para evitar estos tipos de
28762306a36Sopenharmony_ciproblemas de tamaño::
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci    	struct something {
29062306a36Sopenharmony_ci            	size_t count;
29162306a36Sopenharmony_ci            	struct foo items[0];
29262306a36Sopenharmony_ci    	};
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ciPero esto llevó a otros problemas, y no solucionó algunos otros problemas
29562306a36Sopenharmony_cicompartidos por ambos estilos, como no ser capaz de detectar cuando ese array
29662306a36Sopenharmony_ciaccidentalmente _no_ es usado al final de la estructura (lo que podía pasar
29762306a36Sopenharmony_cidirectamente, o cuando dicha estructura era usada en uniones, estructuras
29862306a36Sopenharmony_cide estructuras, etc).
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ciC99 introdujo "los arrays miembros flexibles", los cuales carecen de un
30162306a36Sopenharmony_citamaño numérico en su declaración del array::
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci    	struct something {
30462306a36Sopenharmony_ci            	size_t count;
30562306a36Sopenharmony_ci            	struct foo items[];
30662306a36Sopenharmony_ci    	};
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ciEsta es la forma en la que el kernel espera que se declaren los elementos
30962306a36Sopenharmony_cide tamaño dinámico concatenados. Esto permite al compilador generar
31062306a36Sopenharmony_cierrores, cuando el array flexible no es declarado en el último lugar de la
31162306a36Sopenharmony_ciestructura, lo que ayuda a prevenir errores en él código del tipo
31262306a36Sopenharmony_ci`comportamiento indefinido <https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_.
31362306a36Sopenharmony_ciEsto también permite al compilador analizar correctamente los tamaños de
31462306a36Sopenharmony_cilos arrays (via sizeof(), `CONFIG_FORTIFY_SOURCE`, y `CONFIG_UBSAN_BOUNDS`).
31562306a36Sopenharmony_ciPor ejemplo, si no hay un mecanismo que avise que el siguiente uso de
31662306a36Sopenharmony_cisizeof() en un array de longitud cero, siempre resulta en cero::
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci        struct something {
31962306a36Sopenharmony_ci                size_t count;
32062306a36Sopenharmony_ci                struct foo items[0];
32162306a36Sopenharmony_ci        };
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci        struct something *instance;
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
32662306a36Sopenharmony_ci        instance->count = count;
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci        size = sizeof(instance->items) * instance->count;
32962306a36Sopenharmony_ci        memcpy(instance->items, source, size);
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ciEn la última línea del código anterior, ``zero`` vale ``cero``, cuando uno
33262306a36Sopenharmony_cipodría esperar que representa el tamaño total en bytes de la memoria dinámica
33362306a36Sopenharmony_cireservada para el array consecutivo ``items``. Aquí hay un par de ejemplos
33462306a36Sopenharmony_cimás sobre este tema:  `link 1
33562306a36Sopenharmony_ci<https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_,
33662306a36Sopenharmony_ci`link 2
33762306a36Sopenharmony_ci<https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_.
33862306a36Sopenharmony_ciSin embargo, los array de miembros flexibles tienen un type incompleto, y
33962306a36Sopenharmony_cino se ha de aplicar el operador sizeof()<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_,
34062306a36Sopenharmony_ciasí cualquier mal uso de dichos operadores será detectado inmediatamente en
34162306a36Sopenharmony_ciel momento de compilación.
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ciCon respecto a los arrays de un único elemento, se ha de ser consciente de
34462306a36Sopenharmony_cique dichos arrays ocupan al menos tanto espacio como un único objeto del
34562306a36Sopenharmony_citipo https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_, de ahí que
34662306a36Sopenharmony_ciestos contribuyan al tamaño de la estructura que los contiene. Esto es
34762306a36Sopenharmony_ciproclive a errores cada vez que se quiere calcular el tamaño total de la
34862306a36Sopenharmony_cimemoria dinámica para reservar una estructura que contenga un array de este
34962306a36Sopenharmony_citipo como su miembro::
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci        struct something {
35262306a36Sopenharmony_ci                size_t count;
35362306a36Sopenharmony_ci                struct foo items[1];
35462306a36Sopenharmony_ci        };
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci        struct something *instance;
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci        instance = kmalloc(struct_size(instance, items, count - 1), GFP_KERNEL);
35962306a36Sopenharmony_ci        instance->count = count;
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci        size = sizeof(instance->items) * instance->count;
36262306a36Sopenharmony_ci        memcpy(instance->items, source, size);
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ciEn el ejemplo anterior, hemos de recordar calcular ``count - 1``, cuando se
36562306a36Sopenharmony_ciusa la función de ayuda struct_size(), de otro modo estaríamos
36662306a36Sopenharmony_ci--desintencionadamente--reservando memoria para un  ``items`` de más. La
36762306a36Sopenharmony_ciforma más clara y menos proclive a errores es implementar esto mediante el
36862306a36Sopenharmony_ciuso de `array miembro flexible`, junto con las funciones de ayuda:
36962306a36Sopenharmony_cistruct_size() y flex_array_size()::
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci        struct something {
37262306a36Sopenharmony_ci                size_t count;
37362306a36Sopenharmony_ci                struct foo items[];
37462306a36Sopenharmony_ci        };
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci        struct something *instance;
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
37962306a36Sopenharmony_ci        instance->count = count;
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci        memcpy(instance->items, source, flex_array_size(instance, items, instance->count));
382