From nobody Tue Feb 10 16:58:04 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8363BC433FE for ; Thu, 24 Nov 2022 17:03:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229741AbiKXRDO (ORCPT ); Thu, 24 Nov 2022 12:03:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229693AbiKXRC4 (ORCPT ); Thu, 24 Nov 2022 12:02:56 -0500 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (mail-bn8nam12on2070.outbound.protection.outlook.com [40.107.237.70]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D47EE28E30; Thu, 24 Nov 2022 09:02:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TTcDhea9GaRtShaZFm3HBy9uiJ4U5H3N2mCLUW5IJ4zdURRTXz7XEZgNWsl/Qo2Alff0TIG9RAqmsIDeVfR6ekOf9qh93kXK1DKNkjgTbuGKxGuD9JP26zq+Wl1eCjnShywAqOMmqHeCoas9LSrJTU5u+qqfrLhgp1xkIlnK9Z+SPYc1J+22OfaVOydULu1Vr1xf3w0dbtcSksFr+YaIxx3vgNZ3eeH78EV1QRtDQfa4wXXt8VJq+Bk4ft/Dbr4oIUBo8JmozVftyp31mvRNHD72Pv+5D0WjqoRUzkBQIgt/EKM03W4fzRP+nwdA8iJvggtmSgqx/p1q1uv0WEHiwg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=YAUfC45BKnf0z7do1T0BoRp4YJGArk6DJNFj+9F1qJk=; b=Gheo/PK/2Z1bp4wqcEWZVTdYcnshiYYlT0JBgXOhJ+5qG+85uU6X2ldi+0gJE2by7m15VtlRG8ky2oGJ/Kx/rs0jWA7NV2am399p2WVQfZ76IZ3mxu4LTy/i9hwK0x2xr/bqKEHoc8j85zHnOVUkQuMKxd4zVeK1e0/SgYIPyDzoGymHAqdVbQ6pLh35G92WPFYVSMVt90fFVnQJnS4GtYX1jqW+wL+ihI848WQzbJdQzAFrifksvsQwIk+kVeNICitsq9eNYe6y9/tbPH5u7KUBWixlIZKY3a7mxxezJlhHMzYQzOrM62cjKd59naQLWZJ4MA+n8OdUrRLtTjmgQA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lwn.net smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=YAUfC45BKnf0z7do1T0BoRp4YJGArk6DJNFj+9F1qJk=; b=xqazRO4pEOQl7T2qzFTznbLvpCHp7jhnzcXNCh4HYf6W+BYOoS/mF1U4my9YMX1OIzLD9wu+qzlb/xo8eMxyNNYgFgcjXDdwDg2ZbouLoeP3oPaE5duN0ukWcPliycf+pw5tilYNjLmAJcVx9eCv/qgotFyp8tAvWz0k3XnX5Rc= Received: from DM5PR07CA0081.namprd07.prod.outlook.com (2603:10b6:4:ad::46) by DM6PR12MB4532.namprd12.prod.outlook.com (2603:10b6:5:2af::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5857.19; Thu, 24 Nov 2022 17:02:48 +0000 Received: from DM6NAM11FT004.eop-nam11.prod.protection.outlook.com (2603:10b6:4:ad:cafe::12) by DM5PR07CA0081.outlook.office365.com (2603:10b6:4:ad::46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5857.19 via Frontend Transport; Thu, 24 Nov 2022 17:02:48 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB03.amd.com; pr=C Received: from SATLEXMB03.amd.com (165.204.84.17) by DM6NAM11FT004.mail.protection.outlook.com (10.13.172.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.5834.8 via Frontend Transport; Thu, 24 Nov 2022 17:02:48 +0000 Received: from SATLEXMB05.amd.com (10.181.40.146) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Thu, 24 Nov 2022 11:02:47 -0600 Received: from SATLEXMB04.amd.com (10.181.40.145) by SATLEXMB05.amd.com (10.181.40.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Thu, 24 Nov 2022 11:02:47 -0600 Received: from iron-maiden.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server id 15.1.2375.34 via Frontend Transport; Thu, 24 Nov 2022 11:02:46 -0600 From: Carlos Bilbao To: , , CC: , , , Carlos Bilbao Subject: [PATCH 6/6] docs/sp_SP: Add process coding-style translation Date: Thu, 24 Nov 2022 11:02:42 -0600 Message-ID: <20221124170242.1892751-7-carlos.bilbao@amd.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221124170242.1892751-1-carlos.bilbao@amd.com> References: <20221124170242.1892751-1-carlos.bilbao@amd.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DM6NAM11FT004:EE_|DM6PR12MB4532:EE_ X-MS-Office365-Filtering-Correlation-Id: 5d811f2e-d1e1-4677-46c5-08dace3db6f8 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: rgGqKgAPO7UVco3qWu3/TuP5+phTn3SN7gIZmBO+oG4XD5uizq1ntB/Jj5keuiaZAp6dwAmGwSDxZashTqbQ3OKq7UTaqDnI9BpuUOOdk7iXPOOvBeFFW8GX5EE4m6kDYyZZFKFGgjGU1eIhgmuGwCE0eDrOjowEO49m06/1GZjHeyBnJ+HTSrxCzDZ4JC15Z9opfFlO8RzvghpmAKZM66aXw+f8gXCWXmoAxmYDxSDVRgNw/zgttzwMYVHKgWd4Uhv5PhZ4IdkHa6RtJOzeSVQWRyeRxGhnubSKEZ4RinXpb+XgPy8l42+VbgU6BajbllIUW80bPFZ5YeS3s2MYswrQneyVhGalXDz2RytPGt4FBV9BFcWxPtVerv5ELGPanPviMy148xWvAtEDwOuDhRALBtaAohjEqT7VmqNskuf51ymlynshJ7qkrXO8beLNN7yezfDXOanF1vJzjKwsTCcQkm40dLIJq+sQh6yV4fs9hmI37CoYmDktf4OrbM10U2mKE7WAgnotkprqHVB6ti2z5KXYkJ5JpCzVr2h4+XZk6Hxa2XiSWUHOQl/UX9UOgLWK1R6lPfwR3nrVWJ+8XXD4tQbaCMTaXt2fvvBDVNBBIuhQPfnB5ZIq5AdGcl5XIwwXKNB3Qi7dtDlcdVFTUz+w9OuxDiVeCIM3D+66PGbjSo+fTZ4j27IBIxhf0ctkzD/4esiQcmzq7RODiSeXju7HDAhbrsqqXvuz/JmQ3xM/+FHqRMywx4dztgmu5Und6MucalO+bjwV79CNf5CQFocyRusq7cNouBIzkzGJqro7BBXU90JSMVf5FZ1lKYlm X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:es;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB03.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230022)(4636009)(346002)(136003)(376002)(39860400002)(396003)(451199015)(36840700001)(40470700004)(46966006)(2906002)(82740400003)(356005)(40480700001)(83380400001)(81166007)(8936002)(26005)(36756003)(41300700001)(316002)(54906003)(110136005)(86362001)(2616005)(336012)(186003)(66574015)(426003)(1076003)(47076005)(5660300002)(82310400005)(6666004)(30864003)(44832011)(7696005)(70586007)(36860700001)(70206006)(478600001)(66899015)(8676002)(966005)(4326008)(40460700003)(21314003)(36900700001)(559001)(579004);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Nov 2022 17:02:48.3616 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 5d811f2e-d1e1-4677-46c5-08dace3db6f8 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB03.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DM6NAM11FT004.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4532 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Translate Documentation/process/coding-style.rst into Spanish. Signed-off-by: Carlos Bilbao --- .../sp_SP/process/coding-style.rst | 1315 +++++++++++++++++ .../translations/sp_SP/process/index.rst | 1 + 2 files changed, 1316 insertions(+) create mode 100644 Documentation/translations/sp_SP/process/coding-style.r= st diff --git a/Documentation/translations/sp_SP/process/coding-style.rst b/Do= cumentation/translations/sp_SP/process/coding-style.rst new file mode 100644 index 000000000000..a0261ba5b902 --- /dev/null +++ b/Documentation/translations/sp_SP/process/coding-style.rst @@ -0,0 +1,1315 @@ +.. include:: ../disclaimer-sp.rst + +:Original: :ref:`Documentation/process/coding-style.rst ` +:Translator: Carlos Bilbao + +.. _sp_codingstyle: + +Estilo en el c=C3=B3digo del kernel Linux +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Este es un breve documento que describe el estilo preferido en el c=C3=B3d= igo +del kernel Linux. El estilo de c=C3=B3digo es muy personal y no **forzar= =C3=A9** mi +puntos de vista sobre nadie, pero esto vale para todo lo que tengo que +mantener, y preferir=C3=ADa que para la mayor=C3=ADa de otras cosas tambi= =C3=A9n. Por +favor, por lo menos considere los argumentos expuestos aqu=C3=AD. + +En primer lugar, sugerir=C3=ADa imprimir una copia de los est=C3=A1ndares = de c=C3=B3digo +GNU, y NO leerlo. Qu=C3=A9melos, es un gran gesto simb=C3=B3lico. + +De todos modos, aqu=C3=AD va: + + +1) Sangr=C3=ADa +----------- + +Las tabulaciones tienen 8 caracteres y, por lo tanto, las sangr=C3=ADas ta= mbi=C3=A9n +tienen 8 caracteres. Hay movimientos her=C3=A9ticos que intentan hacer san= gr=C3=ADa +de 4 (=C2=A1o incluso 2!) caracteres de longitud, y eso es similar a trata= r de +definir el valor de PI como 3. + +Justificaci=C3=B3n: La idea detr=C3=A1s de la sangr=C3=ADa es definir clar= amente d=C3=B3nde +comienza y termina un bloque de control. Especialmente, cuando ha estado +buscando en su pantalla durante 20 horas seguidas, le resultar=C3=A1 mucho= m=C3=A1s +f=C3=A1cil ver c=C3=B3mo funciona la sangr=C3=ADa si tiene sangr=C3=ADas g= randes. + +Bueno, algunas personas dir=C3=A1n que tener sangr=C3=ADas de 8 caracteres= hace que +el c=C3=B3digo se mueva demasiado a la derecha y dificulta la lectura en u= na +pantalla de terminal de 80 caracteres. La respuesta a eso es que si +necesita m=C3=A1s de 3 niveles de sangr=C3=ADa, est=C3=A1 en apuros de tod= os modos y +deber=C3=ADa arreglar su programa. + +En resumen, las sangr=C3=ADas de 8 caracteres facilitan la lectura y tiene= n la +ventaja a=C3=B1adida de advertirle cuando est=C3=A1 anidando sus funciones= demasiado +profundo. Preste atenci=C3=B3n a esa advertencia. + +La forma preferida de facilitar m=C3=BAltiples niveles de sangr=C3=ADa en = una +declaraci=C3=B3n de switch es para alinear el ``switch`` y sus etiquetas +``case`` subordinadas en la misma columna, en lugar de hacer ``doble +sangr=C3=ADa`` (``double-indenting``) en etiquetas ``case``. Por ejemplo: + +.. code-block:: c + + switch (suffix) { + case 'G': + case 'g': + mem <<=3D 30; + break; + case 'M': + case 'm': + mem <<=3D 20; + break; + case 'K': + case 'k': + mem <<=3D 10; + fallthrough; + default: + break; + } + +No ponga varias declaraciones en una sola l=C3=ADnea a menos que tenga alg= o que +ocultar: + +.. code-block:: c + + if (condici=C3=B3n) haz_esto; + haz_otra_cosa; + +No use comas para evitar el uso de llaves: + +.. code-block:: c + + if (condici=C3=B3n) + haz_esto(), haz_eso(); + +Siempre use llaves para m=C3=BAltiples declaraciones: + +.. code-block:: c + + if (condici=C3=B3n) { + haz_esto(); + haz_eso(); + } + +Tampoco ponga varias asignaciones en una sola l=C3=ADnea. El estilo de c= =C3=B3digo +del kernel es s=C3=BAper simple. Evite las expresiones enga=C3=B1osas. + + +Aparte de los comentarios, la documentaci=C3=B3n y excepto en Kconfig, los +espacios nunca se utilizan para la sangr=C3=ADa, y el ejemplo anterior se = rompe +deliberadamente. + +Consiga un editor decente y no deje espacios en blanco al final de las +l=C3=ADneas. + +2) Rompiendo l=C3=ADneas y strings largos +------------------------------------ + +El estilo de c=C3=B3digo tiene todo que ver con la legibilidad y la +mantenibilidad usando herramientas disponibles com=C3=BAnmente. + +El l=C3=ADmite preferido en la longitud de una sola l=C3=ADnea es de 80 co= lumnas. + +Las declaraciones de m=C3=A1s de 80 columnas deben dividirse en partes, a = menos +que exceder las 80 columnas aumente significativamente la legibilidad y no +oculte informaci=C3=B3n. + +Los descendientes siempre son sustancialmente m=C3=A1s cortos que el padre= y +se colocan sustancialmente a la derecha. Un estilo muy usado es alinear +descendientes a un par=C3=A9ntesis de funci=C3=B3n abierto. + +Estas mismas reglas se aplican a los encabezados de funciones con una larga +lista de argumentos. + +Sin embargo, nunca rompa los strings visibles para el usuario, como los +mensajes printk, porque eso rompe la capacidad de grep a estos. + + +3) Colocaci=C3=B3n de llaves y espacios +---------------------------------- + +El otro problema que siempre surge en el estilo C es la colocaci=C3=B3n de +llaves. A diferencia del tama=C3=B1o de la sangr=C3=ADa, existen pocas raz= ones +t=C3=A9cnicas para elegir una estrategia de ubicaci=C3=B3n sobre la otra, = pero la +forma preferida, como mostraron los profetas Kernighan y Ritchie, es poner +la llave de apertura en la l=C3=ADnea, y colocar la llave de cierre primer= o, +as=C3=AD: + +.. code-block:: c + + if (x es verdad) { + hacemos y + } + +Esto se aplica a todos los bloques de declaraciones que no son funciones +(if, switch, for, while, do). Por ejemplo: + +.. code-block:: c + + switch (action) { + case KOBJ_ADD: + return "add"; + case KOBJ_REMOVE: + return "remove"; + case KOBJ_CHANGE: + return "change"; + default: + return NULL; + } + +Sin embargo, hay un caso especial, a saber, las funciones: tienen la llave +de apertura al comienzo de la siguiente l=C3=ADnea, as=C3=AD: + +.. code-block:: c + + int funcion(int x) + { + cuerpo de la funci=C3=B3n + } + +Gente hereje de todo el mundo ha afirmado que esta inconsistencia es... +bueno... inconsistente, pero todas las personas sensatas saben que +(a) K&R tienen **raz=C3=B3n** y (b) K&R tienen raz=C3=B3n. Adem=C3=A1s, la= s funciones son +especiales de todos modos (no puede anidarlas en C). + +Tenga en cuenta que la llave de cierre est=C3=A1 vac=C3=ADa en su l=C3=ADn= ea propia, +**excepto** en los casos en que es seguida por una continuaci=C3=B3n de la= misma +declaraci=C3=B3n, es decir, un ``while`` en una sentencia do o un ``else``= en +una sentencia if, como en: + +.. code-block:: c + + do { + cuerpo del bucle do + } while (condition); + +y + +.. code-block:: c + + if (x =3D=3D y) { + .. + } else if (x > y) { + ... + } else { + .... + } + +Justificaci=C3=B3n: K&R. + +Adem=C3=A1s, tenga en cuenta que esta colocaci=C3=B3n de llaves tambi=C3= =A9n minimiza el +n=C3=BAmero de l=C3=ADneas vac=C3=ADas (o casi vac=C3=ADas), sin p=C3=A9rd= ida de legibilidad. As=C3=AD, +como el suministro de nuevas l=C3=ADneas en su pantalla no es un recurso +renovable (piense en pantallas de terminal de 25 l=C3=ADneas), tienes m=C3= =A1s l=C3=ADneas +vac=C3=ADas para poner comentarios. + +No use llaves innecesariamente donde una sola declaraci=C3=B3n sea suficie= nte. + +.. code-block:: c + + if (condition) + accion(); + +y + +.. code-block:: none + + if (condici=C3=B3n) + haz_esto(); + else + haz_eso(); + +Esto no aplica si solo una rama de una declaraci=C3=B3n condicional es una= sola +declaraci=C3=B3n; en este =C3=BAltimo caso utilice llaves en ambas ramas: + +.. code-block:: c + + if (condici=C3=B3n) { + haz_esto(); + haz_eso(); + } else { + en_otro_caso(); + } + +Adem=C3=A1s, use llaves cuando un bucle contenga m=C3=A1s de una declaraci= =C3=B3n simple: + +.. code-block:: c + + while (condici=C3=B3n) { + if (test) + haz_eso(); + } + +3.1) Espacios +************* + +El estilo del kernel Linux para el uso de espacios depende (principalmente) +del uso de funci=C3=B3n versus uso de palabra clave. Utilice un espacio de= spu=C3=A9s +de (la mayor=C3=ADa de) las palabras clave. Las excepciones notables son s= izeof, +typeof, alignof y __attribute__, que parecen algo as=C3=AD como funciones = (y +generalmente se usan con par=C3=A9ntesis en Linux, aunque no son requerido= s en +el idioma, como en: ``sizeof info`` despu=C3=A9s de que ``struct fileinfo = info;`` +se declare). + +As=C3=AD que use un espacio despu=C3=A9s de estas palabras clave:: + + if, switch, case, for, do, while + +pero no con sizeof, typeof, alignof, o __attribute__. Por ejemplo, + +.. code-block:: c + + + s =3D sizeof(struct file); + +No agregue espacios alrededor (dentro) de expresiones entre par=C3=A9ntesi= s. +Este ejemplo es **malo**: + +.. code-block:: c + + + s =3D sizeof( struct file ); + +Al declarar datos de puntero o una funci=C3=B3n que devuelve un tipo de pu= ntero, +el uso preferido de ``*`` es adyacente al nombre del dato o nombre de la +funci=C3=B3n y no junto al nombre del tipo. Ejemplos: + +.. code-block:: c + + + char *linux_banner; + unsigned long long memparse(char *ptr, char **retptr); + char *match_strdup(substring_t *s); + +Use un espacio alrededor (a cada lado de) la mayor=C3=ADa de los operadores +binarios y ternarios, como cualquiera de estos:: + + =3D + - < > * / % | & ^ <=3D >=3D =3D=3D !=3D ? : + +pero sin espacio despu=C3=A9s de los operadores unarios:: + + & * + - ~ ! sizeof typeof alignof __attribute__ defined + +sin espacio antes de los operadores unarios de incremento y decremento del +sufijo:: + + ++ -- + +y sin espacio alrededor de los operadores de miembros de estructura ``.`` y +``->``. + +No deje espacios en blanco al final de las l=C3=ADneas. Algunos editores c= on +``inteligente`` sangr=C3=ADa insertar=C3=A1n espacios en blanco al comienz= o de las +nuevas l=C3=ADneas como sea apropiado, para que pueda comenzar a escribir = la +siguiente l=C3=ADnea de c=C3=B3digo de inmediato. Sin embargo, algunos de = estos +editores no eliminan los espacios en blanco si finalmente no termina +poniendo una l=C3=ADnea de c=C3=B3digo all=C3=AD, como si dejara una l=C3= =ADnea en blanco. Como +resultado, termina con l=C3=ADneas que contienen espacios en blanco al fin= al. + +Git le advertir=C3=A1 sobre los parches que introducen espacios en blanco = al +final y puede, opcionalmente, eliminar los espacios en blanco finales por +usted; sin embargo, si se aplica una serie de parches, esto puede hacer que +los parches posteriores de la serie fallen al cambiar sus l=C3=ADneas de +contexto. + + +4) Nomenclatura +--------------- + +C es un lenguaje espartano, y sus convenciones de nomenclatura deber=C3=AD= an +seguir su ejemplo. A diferencia de los programadores de Modula-2 y Pascal, +los programadores de C no usan nombres cuquis como +EstaVariableEsUnContadorTemporal. Un programador de C lo llamar=C3=ADa +variable ``tmp``, que es mucho m=C3=A1s f=C3=A1cil de escribir, y no es ma= s dif=C3=ADcil +de comprender. + +SIN EMBARGO, mientras que los nombres de may=C3=BAsculas y min=C3=BAsculas= est=C3=A1n mal +vistos, los nombres descriptivos para las variables globales son +imprescindibles. Llamar a una funci=C3=B3n global ``foo`` es un delito. + +Una variable GLOBAL (para usar solo si **realmente** las necesita) necesita +tener un nombre descriptivo, al igual que las funciones globales. Si tiene +una funci=C3=B3n que cuenta el n=C3=BAmero de usuarios activos, debe llama= r a esta +``contar_usuarios_activos()`` o similar, **no** debe llamarlo ``cntusr()``. + +Codificar el tipo de una funci=C3=B3n en el nombre (lo llamado notaci=C3= =B3n h=C3=BAngara) +es est=C3=BApido: el compilador conoce los tipos de todos modos y puede +verificar estos, y solo confunde al programador. + +Los nombres de las variables LOCALES deben ser breves y directos. Si usted +tiene alg=C3=BAn contador aleatorio de tipo entero, probablemente deber=C3= =ADa +llamarse ``i``. Llamarlo ``loop_counter`` no es productivo, si no hay +posibilidad de ser mal entendido. De manera similar, ``tmp`` puede ser casi +cualquier tipo de variable que se utiliza para contener un valor temporal. + +Si tiene miedo de mezclar los nombres de las variables locales, tiene otro +problema, que se denomina s=C3=ADndrome de +funci=C3=B3n-crecimiento-desequilibrio-de-hormona. Vea el cap=C3=ADtulo 6 = (Funciones). + +Para nombres de s=C3=ADmbolos y documentaci=C3=B3n, evite introducir nuevo= s usos de +'master / slave' (maestro / esclavo) (o 'slave' independientemente de +'master') y 'lista negra / lista blanca' (backlist / whitelist). + +Los reemplazos recomendados para 'maestro / esclavo' son: + '{primary,main} / {secondary,replica,subordinate}' + '{initiator,requester} / {target,responder}' + '{controller,host} / {device,worker,proxy}' + 'leader / follower' + 'director / performer' + +Los reemplazos recomendados para 'backlist / whitelist' son: + 'denylist / allowlist' + 'blocklist / passlist' + +Las excepciones para la introducci=C3=B3n de nuevos usos son mantener en e= spacio +de usuario una ABI/API, o al actualizar la especificaci=C3=B3n del c=C3=B3= digo de un +hardware o protocolo existente (a partir de 2020) que requiere esos +t=C3=A9rminos. Para nuevas especificaciones, traduzca el uso de la termino= log=C3=ADa +de la especificaci=C3=B3n al est=C3=A1ndar de c=C3=B3digo del kernel donde= sea posible. + +5) Typedefs +----------- + +Por favor no use cosas como ``vps_t``. +Es un **error** usar typedef para estructuras y punteros. cuando ve un + +.. code-block:: c + + + vps_t a; + +en el c=C3=B3digo fuente, =C2=BFqu=C3=A9 significa? +En cambio, si dice + +.. code-block:: c + + struct virtual_container *a; + +puede decir qu=C3=A9 es ``a`` en realidad. + +Mucha gente piensa que los typedefs ``ayudan a la legibilidad``. No. Son +=C3=BAtiles solamente para: + + (a) objetos totalmente opacos (donde el typedef se usa activamente para + **ocultar** cu=C3=A1l es el objeto). + + Ejemplo: ``pte_t`` etc. objetos opacos a los que solo puede acceder + usando las funciones de acceso adecuadas. + + .. note:: + + La opacidad y las ``funciones de acceso`` no son buenas por s=C3=AD + mismas. La raz=C3=B3n por la que los tenemos para cosas como pte_t,= etc. + es que hay real y absolutamente **cero** informaci=C3=B3n accesible= de + forma port=C3=A1til all=C3=AD. + + (b) Tipos enteros claros, donde la abstracci=C3=B3n **ayuda** a evitar + confusiones, ya sea ``int`` o ``long``. + + u8/u16/u32 son definiciones tipogr=C3=A1ficas perfectamente correctas + aunque encajan en la categor=C3=ADa (d) mejor que aqu=C3=AD. + + .. note:: + + De nuevo - debe haber una **raz=C3=B3n** para esto. si algo es + ``unsigned long``, entonces no hay raz=C3=B3n para hacerlo + + typedef unsigned long mis_flags_t; + + pero si hay una raz=C3=B3n clara de por qu=C3=A9 bajo ciertas circuns= tancias + podr=C3=ADa ser un ``unsigned int`` y bajo otras configuraciones podr= =C3=ADa + ser ``unsigned long``, entonces, sin duda, adelante y use un typedef. + + (c) cuando lo use para crear literalmente un tipo **nuevo** para + comprobaci=C3=B3n de tipos. + + (d) Nuevos tipos que son id=C3=A9nticos a los tipos est=C3=A1ndar C99, en= ciertas + circunstancias excepcionales. + + Aunque s=C3=B3lo costar=C3=ADa un corto per=C3=ADodo de tiempo para l= os ojos y + cerebro para acostumbrarse a los tipos est=C3=A1ndar como ``uint32_t`= `, + algunas personas se oponen a su uso de todos modos. + + Por lo tanto, los tipos ``u8/u16/u32/u64`` espec=C3=ADficos de Linux = y sus + equivalentes con signo, que son id=C3=A9nticos a los tipos est=C3=A1n= dar son + permitidos, aunque no son obligatorios en el nuevo c=C3=B3digo de su + elecci=C3=B3n. + + Al editar c=C3=B3digo existente que ya usa uno u otro conjunto de tip= os, + debe ajustarse a las opciones existentes en ese c=C3=B3digo. + + (e) Tipos seguros para usar en el espacio de usuario. + + En ciertas estructuras que son visibles para el espacio de usuario, no + podemos requerir tipos C99 y o utilizat el ``u32`` anterior. Por lo + tanto, usamos __u32 y tipos similares en todas las estructuras que se + comparten con espacio de usuario. + +Tal vez tambi=C3=A9n haya otros casos, pero la regla b=C3=A1sicamente debe= r=C3=ADa ser +NUNCA JAM=C3=81S use un typedef a menos que pueda coincidir claramente con= una +de estas reglas. + +En general, un puntero o una estructura que tiene elementos que pueden +ser razonablemente accedidos directamente, **nunca** deben ser un typedef. + +6) Funciones +------------ + +Las funciones deben ser cortas y dulces, y hacer una sola cosa. Deber=C3= =ADan +caber en una o dos pantallas de texto (el tama=C3=B1o de pantalla ISO/ANSI= es +80x24, como todos sabemos), y hacer una cosa y hacerla bien. + +La longitud m=C3=A1xima de una funci=C3=B3n es inversamente proporcional a= la +complejidad y el nivel de sangr=C3=ADa de esa funci=C3=B3n. Entonces, si t= iene una +funci=C3=B3n conceptualmente simple que es solo una larga (pero simple) +declaraci=C3=B3n de case, donde tiene que hacer un mont=C3=B3n de peque=C3= =B1as cosas para +un mont=C3=B3n de diferentes casos, est=C3=A1 bien tener una funci=C3=B3n = m=C3=A1s larga. + +Sin embargo, si tiene una funci=C3=B3n compleja y sospecha que un estudian= te de +primer a=C3=B1o de secundaria menos que dotado podr=C3=ADa no comprender d= e qu=C3=A9 se +trata la funci=C3=B3n, debe adherirse a los l=C3=ADmites m=C3=A1ximos tant= o m=C3=A1s de +cerca. Use funciones auxiliares con nombres descriptivos (puede pedirle al +compilador que los alinee si cree que es cr=C3=ADtico para el rendimiento,= y +probablemente lo har=C3=A1 mejor de lo que usted hubiera hecho). + +Otra medida de la funci=C3=B3n es el n=C3=BAmero de variables locales. Est= as no deben +exceder de 5 a 10, o est=C3=A1 haciendo algo mal. Piense de nuevo en la fu= nci=C3=B3n +y divida en partes m=C3=A1s peque=C3=B1as. Un cerebro humano puede general= mente +realiza un seguimiento de aproximadamente 7 cosas diferentes, cualquier +elemento m=C3=A1s y se confunde. Usted sabe que es brillante, pero tal vez= le +gustar=C3=ADa entender lo que hizo dentro de 2 semanas. + +En los archivos fuente, separe las funciones con una l=C3=ADnea en blanco.= Si la +funci=C3=B3n es exportada, la macro **EXPORT** deber=C3=ADa ponerse inmedi= atamente +despu=C3=A9s de la funci=C3=B3n de cierre de l=C3=ADnea de llave. Por ejem= plo: + +.. code-block:: c + + int sistema_corriendo(void) + { + return estado_sistema =3D=3D SISTEMA_CORRIENDO; + } + EXPORT_SYMBOL(sistema_corriendo); + +6.1) Prototipos de funciones +**************************** + +En los prototipos de funciones, incluya nombres de par=C3=A1metros con sus= tipos +de datos. Aunque esto no es requerido por el lenguaje C, se prefiere en +Linux porque es una forma sencilla de a=C3=B1adir informaci=C3=B3n valiosa= para el +lector. + +No utilice la palabra clave ``extern`` con declaraciones de funci=C3=B3n y= a que +esto hace las l=C3=ADneas m=C3=A1s largas y no es estrictamente necesario. + +Al escribir prototipos de funciones, mantenga el `orden de los elementos r= egular +`_. +Por ejemplo, usando este ejemplo de declaraci=C3=B3n de funci=C3=B3n:: + + __init void * __must_check action(enum magic value, size_t size, u8 count, + char *fmt, ...) __printf(4, 5) __malloc; + +El orden preferido de elementos para un prototipo de funci=C3=B3n es: + +- clase de almacenamiento (a continuaci=C3=B3n, ``static __always_inline``, + teniendo en cuenta que ``__always_inline`` es t=C3=A9cnicamente un atrib= uto + pero se trata como ``inline``) +- atributos de clase de almacenamiento (aqu=C3=AD, ``__init`` -- es decir, + declaraciones de secci=C3=B3n, pero tambi=C3=A9n cosas como ``__cold``) +- tipo de retorno (aqu=C3=AD, ``void *``) +- atributos de tipo de retorno (aqu=C3=AD, ``__must_check``) +- nombre de la funci=C3=B3n (aqu=C3=AD, ``action``) +- par=C3=A1metros de la funci=C3=B3n (aqu=C3=AD, ``(enum magic value, size= _t size, u8 count, char *fmt, ...)``, + teniendo en cuenta que los nombres de los par=C3=A1metros siempre deben + incluirse) +- atributos de par=C3=A1metros de funci=C3=B3n (aqu=C3=AD, ``__printf(4, 5= )``) +- atributos de comportamiento de la funci=C3=B3n (aqu=C3=AD, ``__malloc``) + +Tenga en cuenta que para una **definici=C3=B3n** de funci=C3=B3n (es decir= , el cuerpo +real de la funci=C3=B3n), el compilador no permite atributos de par=C3=A1m= etros de +funci=C3=B3n despu=C3=A9s de par=C3=A1metros de la funci=C3=B3n. En estos = casos, deber=C3=A1n ir +tras los atributos de clase (por ejemplo, tenga en cuenta el cambio de +posici=C3=B3n de ``__printf(4, 5)`` a continuaci=C3=B3n, en comparaci=C3= =B3n con el +ejemplo de **declaraci=C3=B3n** anterior):: + + static __always_inline __init __printf(4, 5) void * __must_check action(e= num magic value, + size_t size, u8 count, char *fmt, ...) __malloc + { + ... + } + +7) Salida centralizada de funciones +----------------------------------- + +Aunque desaprobado por algunas personas, el equivalente de la instrucci=C3= =B3n +goto es utilizado con frecuencia por los compiladores, en forma de +instrucci=C3=B3n de salto incondicional. + +La declaraci=C3=B3n goto es =C3=BAtil cuando una funci=C3=B3n sale desde m= =C3=BAltiples +ubicaciones y se deben realizar algunos trabajos comunes, como la limpieza. +Si no se necesita limpieza, entonces simplemente haga return directamente. + +Elija nombres de etiquetas que digan qu=C3=A9 hace el goto o por qu=C3=A9 = existe el +goto. Un ejemplo de un buen nombre podr=C3=ADa ser ``out_free_buffer:`` +(``salida_liberar_buffer``) si al irse libera ``buffer``. Evite usar +nombres GW-BASIC como ``err1:`` y ``err2:``, ya que tendr=C3=ADa que volve= r a +numerarlos si alguna vez agrega o elimina rutas de salida, y hacen que sea +dif=C3=ADcil de verificar que sean correctos, de todos modos. + +La raz=C3=B3n para usar gotos es: + +- Las declaraciones incondicionales son m=C3=A1s f=C3=A1ciles de entender = y seguir. +- se reduce el anidamiento +- errores al no actualizar los puntos de salida individuales al hacer + modificaciones son evitados +- ahorra el trabajo del compilador de optimizar c=C3=B3digo redundante ;) + +.. code-block:: c + + int fun(int a) + { + int result =3D 0; + char *buffer; + + buffer =3D kmalloc(SIZE, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + if (condition1) { + while (loop1) { + ... + } + result =3D 1; + goto out_free_buffer; + } + ... + out_free_buffer: + kfree(buffer); + return result; + } + +Un tipo com=C3=BAn de error a tener en cuenta es "un error de error" que e= s algo +as=C3=AD: + +.. code-block:: c + + err: + kfree(foo->bar); + kfree(foo); + return ret; + +El error en este c=C3=B3digo es que en algunas rutas de salida, ``foo`` es= NULL. +Normalmente la soluci=C3=B3n para esto es dividirlo en dos etiquetas de er= ror +``err_free_bar:`` y ``err_free_foo:``: + +.. code-block:: c + + err_free_bar: + kfree(foo->bar); + err_free_foo: + kfree(foo); + return ret; + +Idealmente, deber=C3=ADa simular errores para probar todas las rutas de sa= lida. + + +8) Comentarios +-------------- + +Los comentarios son buenos, pero tambi=C3=A9n existe el peligro de comentar +demasiado. NUNCA trate de explicar C=C3=93MO funciona su c=C3=B3digo en un +comentario: es mucho mejor escribir el c=C3=B3digo para que el +**funcionamiento** sea obvio y es una p=C3=A9rdida de tiempo explicar c=C3= =B3digo mal +escrito. + +Generalmente, desea que sus comentarios digan QU=C3=89 hace su c=C3=B3digo= , no C=C3=93MO. +Adem=C3=A1s, trate de evitar poner comentarios dentro del cuerpo de una fu= nci=C3=B3n: +si la funci=C3=B3n es tan compleja que necesita comentar por separado part= es de +esta, probablemente deber=C3=ADa volver al cap=C3=ADtulo 6 una temporada. = Puede +hacer peque=C3=B1os comentarios para notar o advertir sobre algo particula= rmente +inteligente (o feo), pero trate de evitar el exceso. En su lugar, ponga los +comentarios al principio de la funci=C3=B3n, diga a la gente lo que hace y +posiblemente POR QU=C3=89 hace esto. + +Al comentar las funciones de la API del kernel, utilice el formato +kernel-doc. Consulte los archivos en :ref:`Documentation/doc-guide/ ` +y ``scripts/kernel-doc`` para m=C3=A1s detalles. + +El estilo preferido para comentarios largos (de varias l=C3=ADneas) es: + +.. code-block:: c + + /* + * Este es el estilo preferido para comentarios + * multil=C3=ADnea en el c=C3=B3digo fuente del kernel Linux. + * Por favor, util=C3=ADcelo constantemente. + * + * Descripci=C3=B3n: Una columna de asteriscos en el lado izquierdo, + * con l=C3=ADneas iniciales y finales casi en blanco. + */ + +Para archivos en net/ y drivers/net/, el estilo preferido para comentarios +largos (multi-linea) es un poco diferente. + +.. code-block:: c + + /* El estilo de comentario preferido para archivos en net/ y drivers/net + * se asemeja a esto. + * + * Es casi lo mismo que el estilo de comentario generalmente preferido, + * pero no hay una l=C3=ADnea inicial casi en blanco. + */ + +Tambi=C3=A9n es importante comentar los datos, ya sean tipos b=C3=A1sicos o +derivados. Para este fin, use solo una declaraci=C3=B3n de datos por l=C3= =ADnea (sin +comas para m=C3=BAltiples declaraciones de datos). Esto le deja espacio pa= ra un +peque=C3=B1o comentario sobre cada elemento, explicando su uso. + +9) Has hecho un desastre +--------------------------- + +Est=C3=A1 bien, todos lo hacemos. Probablemente un antiguo usuario de Unix= le +haya dicho que ``GNU emacs`` formatea autom=C3=A1ticamente las fuentes C p= or +usted, y ha notado que s=C3=AD, lo hace, pero los por defecto que tiene son +menos que deseables (de hecho, son peores que los aleatorios) escribiendo - +un n=C3=BAmero infinito de monos escribiendo en GNU emacs nunca har=C3=A1n= un buen +programa). + +Por lo tanto, puede deshacerse de GNU emacs o cambiarlo y usar valores m= =C3=A1s +sanos. Para hacer esto =C3=BAltimo, puede pegar lo siguiente en su archivo +.emacs: + +.. code-block:: none + + (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) + +Esto har=C3=A1 que emacs funcione mejor con el estilo de c=C3=B3digo del k= ernel para +C en archivos bajo ``~/src/linux-trees``. + +Pero incluso si no logra que emacs realice un formateo correcto, no todo +est=C3=A1 perdido: use ``indent``. + +Ahora bien, de nuevo, la sangr=C3=ADa de GNU tiene la misma configuraci=C3= =B3n de +muerte cerebral que GNU emacs tiene, por lo que necesita darle algunas +opciones de l=C3=ADnea de comando. Sin embargo, eso no es tan malo, porque +incluso los creadores de GNU indent reconocen la autoridad de K&R (la gente +de GNU no es mala, solo est=C3=A1n gravemente equivocados en este asunto),= por +lo que simplemente de a la sangr=C3=ADa las opciones ``-kr -i8`` (significa +``K&R, guiones de 8 caracteres``), o use ``scripts/Lindent``, que indenta +con ese estilo. + +``indent`` tiene muchas opciones, y especialmente cuando se trata de +comentar reformateos, es posible que desee echar un vistazo a la p=C3=A1gi= na del +manual. Pero recuerde: ``indent`` no es la soluci=C3=B3n para una mala +programaci=C3=B3n. + +Tenga en cuenta que tambi=C3=A9n puede usar la herramienta ``clang-format`= ` para +ayudarlo con estas reglas, para volver a formatear r=C3=A1pidamente partes= de su +c=C3=B3digo autom=C3=A1ticamente, y revisar archivos completos para detect= ar errores +de estilo del c=C3=B3digo, errores tipogr=C3=A1ficos y posibles mejoras. T= ambi=C3=A9n es +=C3=BAtil para ordenar ``#includes``, para alinear variables/macros, para +redistribuir texto y otras tareas similares. Vea el archivo +:ref:`Documentation/process/clang-format.rst ` para m=C3=A1s +detalles. + +10) Archivos de configuraci=C3=B3n de Kconfig +---------------------------------------- + +Para todos los archivos de configuraci=C3=B3n de Kconfig* en todo el =C3= =A1rbol +fuente, la sangr=C3=ADa es algo diferente. Las l=C3=ADneas bajo una defini= ci=C3=B3n +``config`` est=C3=A1n indentadas con una tabulaci=C3=B3n, mientras que el = texto de +ayuda tiene una sangr=C3=ADa adicional de dos espacios. Ejemplo:: + + config AUDIT + bool "Soporte para auditar" + depends on NET + help + Habilita la infraestructura de auditor=C3=ADa que se puede usar con otro + subsistema kernel, como SELinux (que requiere esto para + registro de salida de mensajes avc). No hace auditor=C3=ADa de llamadas= al + sistema sin CONFIG_AUDITSYSCALL. + +Caracter=C3=ADsticas seriamente peligrosas (como soporte de escritura para +ciertos filesystems) deben anunciar esto de forma destacada en su cadena de +solicitud:: + + config ADFS_FS_RW + bool "ADFS write support (DANGEROUS)" + depends on ADFS_FS + ... + +Para obtener la documentaci=C3=B3n completa sobre los archivos de configur= aci=C3=B3n, +consulte el archivo Documentation/kbuild/kconfig-language.rst. + + +11) Estructuras de datos +------------------------ + +Las estructuras de datos que tienen visibilidad fuera del contexto de un +solo subproceso en el que son creadas y destruidas, siempre debe tener +contadores de referencia. En el kernel, la recolecci=C3=B3n de basura no e= xiste +(y fuera, la recolecci=C3=B3n de basura del kernel es lenta e ineficiente)= , lo +que significa que absolutamente **tiene** para hacer referencia y contar +todos sus usos. + +El conteo de referencias significa que puede evitar el bloqueo y permite +que m=C3=BAltiples usuarios tengan acceso a la estructura de datos en para= lelo - +y no tengan que preocuparse de que la estructura, de repente, desaparezca +debajo de su control, solo porque durmieron o hicieron otra cosa por un +tiempo. + +Tenga en cuenta que el bloqueo **no** reemplaza el recuento de referencia. +El bloqueo se utiliza para mantener la coherencia de las estructuras de +datos, mientras que la referencia y contar es una t=C3=A9cnica de gesti=C3= =B3n de +memoria. Por lo general, ambos son necesarios, y no deben confundirse entre +s=C3=AD. + +De hecho, muchas estructuras de datos pueden tener dos niveles de conteo de +referencias, cuando hay usuarios de diferentes ``clases``. El conteo de +subclases cuenta el n=C3=BAmero de usuarios de la subclase y disminuye el = conteo +global solo una vez, cuando el recuento de subclases llega a cero. + +Se pueden encontrar ejemplos de este tipo de ``recuento de referencias de +niveles m=C3=BAltiples`` en la gesti=C3=B3n de memoria (``struct mm_struct= ``: +mm_users y mm_count), y en c=C3=B3digo del sistema de archivos +(``struct super_block``: s_count y s_active). + +Recuerde: si otro hilo puede encontrar su estructura de datos y usted no +tiene un recuento de referencias, es casi seguro que tiene un error. + +12) Macros, Enums y RTL +------------------------ + +Los nombres de macros que definen constantes y etiquetas en enumeraciones +(enums) est=C3=A1n en may=C3=BAsculas. + +.. code-block:: c + + #define CONSTANTE 0x12345 + +Se prefieren los enums cuando se definen varias constantes relacionadas. + +Se aprecian los nombres de macro en MAY=C3=9ASCULAS, pero las macros que se +asemejan a funciones puede ser nombradas en min=C3=BAscula. + +Generalmente, las funciones en l=C3=ADnea son preferibles a las macros que= se +asemejan a funciones. + +Las macros con varias instrucciones deben contenerse en un bloque do-while: + +.. code-block:: c + + #define macrofun(a, b, c) \ + do { \ + if (a =3D=3D 5) \ + haz_esto(b, c); \ + } while (0) + +Cosas a evitar al usar macros: + +1) macros que afectan el flujo de control: + +.. code-block:: c + + #define FOO(x) \ + do { \ + if (blah(x) < 0) \ + return -EBUGGERED; \ + } while (0) + +es una **muy** mala idea. Parece una llamada de funci=C3=B3n pero sale de = la +funci=C3=B3n de ``llamada``; no rompa los analizadores internos de aquello= s que +leer=C3=A1n el c=C3=B3digo. + +2) macros que dependen de tener una variable local con un nombre m=C3=A1gi= co: + +.. code-block:: c + + #define FOO(val) bar(index, val) + +puede parecer algo bueno, pero es confuso como el infierno cuando uno lee +el c=C3=B3digo, y es propenso a romperse por cambios aparentemente inocent= es. + +3) macros con argumentos que se usan como valores l: FOO(x) =3D y; le van +a morder si alguien, por ejemplo, convierte FOO en una funci=C3=B3n en l= =C3=ADnea. + +4) olvidarse de la precedencia: las macros que definen constantes usando +expresiones deben encerrar la expresi=C3=B3n entre par=C3=A9ntesis. Tenga = cuidado con +problemas similares con macros usando par=C3=A1metros. + +.. code-block:: c + + #define CONSTANTE 0x4000 + #define CONSTEXP (CONSTANTE | 3) + +5) colisiones de espacio de nombres ("namespace") al definir variables +locales en macros que se asemejan a funciones: + +.. code-block:: c + + #define FOO(x) \ + ({ \ + typeof(x) ret; \ + ret =3D calc_ret(x); \ + (ret); \ + }) + +ret es un nombre com=C3=BAn para una variable local -es menos probable que +__foo_ret colisione (coincida) con una variable existente. + +El manual de cpp trata las macros de forma exhaustiva. El manual interno de +gcc tambi=C3=A9n cubre RTL, que se usa frecuentemente con lenguaje ensambl= ador +en el kernel. + +13) Imprimir mensajes del kernel +-------------------------------- + +A los desarrolladores del kernel les gusta ser vistos como alfabetizados. +Cuide la ortograf=C3=ADa de los mensajes del kernel para causar una buena +impresi=C3=B3n. No utilice contracciones incorrectas como ``dont``; use +``do not`` o ``don't`` en su lugar. Haga sus mensajes concisos, claros e +inequ=C3=ADvocos. + +Los mensajes del kernel no tienen que terminar con un punto. + +Imprimir n=C3=BAmeros entre par=C3=A9ntesis (%d) no agrega valor y debe ev= itarse. + +Hay varias modelos de macros de diagn=C3=B3stico de driver en +que debe usar para asegurarse de que los mensajes coincidan con el +dispositivo correcto y driver, y est=C3=A1n etiquetados con el nivel corre= cto: +dev_err(), dev_warn(), dev_info(), y as=C3=AD sucesivamente. Para mensajes= que +no est=C3=A1n asociados con un dispositivo particular, de= fine +pr_notice(), pr_info(), pr_warn(), pr_err(), etc. + +Crear buenos mensajes de depuraci=C3=B3n puede ser todo un desaf=C3=ADo; y= una vez +los tiene, pueden ser de gran ayuda para la resoluci=C3=B3n remota de prob= lemas. +Sin embargo, la impresi=C3=B3n de mensajes de depuraci=C3=B3n se maneja de= manera +diferente a la impresi=C3=B3n de otros mensajes que no son de depuraci=C3= =B3n. +Mientras que las otras funciones pr_XXX() se imprimen incondicionalmente, +pr_debug() no lo hace; se compila fuera por defecto, a menos que DEBUG sea +definido o se establezca CONFIG_DYNAMIC_DEBUG. Eso es cierto para dev_dbg() +tambi=C3=A9n, y una convenci=C3=B3n relacionada usa VERBOSE_DEBUG para agr= egar +mensajes dev_vdbg() a los ya habilitados por DEBUG. + +Muchos subsistemas tienen opciones de depuraci=C3=B3n de Kconfig para acti= var +-DDEBUG en el Makefile correspondiente; en otros casos, los archivos +usan #define DEBUG. Y cuando un mensaje de depuraci=C3=B3n debe imprimirse +incondicionalmente, por ejemplo si es ya dentro de una secci=C3=B3n #ifdef +relacionada con la depuraci=C3=B3n, printk(KERN_DEBUG ...) puede ser usado. + +14) Reservando memoria +---------------------- + +El kernel proporciona los siguientes asignadores de memoria de prop=C3=B3s= ito +general: kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc() y +vzalloc(). Consulte la documentaci=C3=B3n de la API para obtener m=C3=A1s = informaci=C3=B3n. +a cerca de ellos. :ref:`Documentation/core-api/memory-allocation.rst +` + +La forma preferida para pasar el tama=C3=B1o de una estructura es la sigui= ente: + +.. code-block:: c + + p =3D kmalloc(sizeof(*p), ...); + +La forma alternativa donde se deletrea el nombre de la estructura perjudica +la legibilidad, y presenta una oportunidad para un error cuando se cambia +el tipo de variable de puntero, pero el tama=C3=B1o correspondiente de eso= que +se pasa a un asignador de memoria no. + +Convertir el valor devuelto, que es un puntero vac=C3=ADo, es redundante. = La +conversi=C3=B3n desde el puntero vac=C3=ADo a cualquier otro tipo de punte= ro est=C3=A1 +garantizado por la programaci=C3=B3n en idioma C. + +La forma preferida para asignar una matriz es la siguiente: + +.. code-block:: c + + p =3D kmalloc_array(n, sizeof(...), ...); + +La forma preferida para asignar una matriz a cero es la siguiente: + +.. code-block:: c + + p =3D kcalloc(n, sizeof(...), ...); + +Ambos casos verifican el desbordamiento en el tama=C3=B1o de asignaci=C3= =B3n n * +sizeof (...), y devuelven NULL si esto ocurri=C3=B3. + +Todas estas funciones de asignaci=C3=B3n gen=C3=A9ricas emiten un volcado = de pila +(" stack dump") en caso de fallo cuando se usan sin __GFP_NOWARN, por lo +que no sirve de nada emitir un mensaje de fallo adicional cuando se +devuelva NULL. + +15) La enfermedad de inline +---------------------------- + +Parece haber una com=C3=BAn percepci=C3=B3n err=C3=B3nea de que gcc tiene = una magica +opci=C3=B3n "hazme m=C3=A1s r=C3=A1pido" de aceleraci=C3=B3n, llamada ``in= line`` (en l=C3=ADnea). +Mientras que el uso de inlines puede ser apropiado (por ejemplo, como un +medio para reemplazar macros, consulte el Cap=C3=ADtulo 12), muy a menudo = no lo +es. El uso abundante de la palabra clave inline conduce a una mayor kernel, +que a su vez ralentiza el sistema en su conjunto, debido a una mayor huella +de icache para la CPU, y sencillamente porque hay menos memoria disponible +para el pagecache. Solo piense en esto; un fallo en la memoria cach=C3=A9 = de la +p=C3=A1gina provoca una b=C3=BAsqueda de disco, que tarda f=C3=A1cilmente = 5 milisegundos. +Hay MUCHOS ciclos de CPU que puede entrar en estos 5 milisegundos. + +Una razonable regla general es no poner funciones inline que tengan m=C3= =A1s de +3 l=C3=ADneas de c=C3=B3digo en ellas. Una excepci=C3=B3n a esta regla son= los casos en +que se sabe que un par=C3=A1metro es una constante en tiempo de compilaci= =C3=B3n, y +como resultado de esto, usted *sabe*, el compilador podr=C3=A1 optimizar la +mayor parte de su funci=C3=B3n en tiempo de compilaci=C3=B3n. Para un buen= ejemplo de +este =C3=BAltimo caso, v=C3=A9ase la funci=C3=B3n en l=C3=ADnea kmalloc(). + +A menudo, la gente argumenta que agregar funciones en l=C3=ADnea que son +est=C3=A1ticas y se usan solo una vez, es siempre una victoria ya que no h= ay +perdida de espacio. Mientras esto es t=C3=A9cnicamente correcto, gcc es ca= paz de +incorporarlos autom=C3=A1ticamente sin ayuda, y esta el problema de +mantenimiento de eliminar el inline, cuando un segundo usuario supera el +valor potencial de la pista que le dice a gcc que haga algo que habr=C3=ADa +hecho de todos modos. + +16) Valores devueltos por funci=C3=B3n y sus nombres +----------------------------------------------- + +Las funciones pueden devolver valores de muchos tipos diferentes, y uno de +lo m=C3=A1s com=C3=BAn es un valor que indica si la funci=C3=B3n tuvo =C3= =A9xito o ha fallado. +Dicho valor se puede representar como un n=C3=BAmero entero de c=C3=B3digo= de error +(-Exxx =3D falla, 0 =3D =C3=A9xito) o un booleano ``con =C3=A9xito`` (0 = =3D falla, distinto +de cero =3D =C3=A9xito). + +La mezcla de estos dos tipos de representaciones es una fuente f=C3=A9rtil= de +errores dif=C3=ADciles de encontrar. Si el lenguaje C incluyera una fuerte +distinci=C3=B3n entre enteros y booleanos, el compilador encontrar=C3=ADa = estos +errores por nosotros... pero no lo hace. Para ayudar a prevenir tales +errores, siga siempre esta convenci=C3=B3n:: + + Si el nombre de una funci=C3=B3n es una acci=C3=B3n o un comando imperati= vo, + la funci=C3=B3n debe devolver un n=C3=BAmero entero de c=C3=B3digo de err= or. si el nombre + es un predicado, la funci=C3=B3n debe devolver un valor booleano "exitoso= ". + +Por ejemplo, ``agregar trabajo`` es un comando, y la funci=C3=B3n +agregar_trabajo() devuelve 0 en caso de =C3=A9xito o -EBUSY en caso de fra= caso. +De la misma manera, ``dispositivo PCI presente`` es un predicado, y la +funci=C3=B3n pci_dev_present() devuelve 1 si tiene =C3=A9xito en encontrar= un +dispositivo coincidente o 0 si no es as=C3=AD. + +Todas las funciones EXPORTed (exportadas) deben respetar esta convenci=C3= =B3n, +al igual que todas las funciones publicas. Las funciones privadas +(est=C3=A1ticas) no lo necesitan, pero es recomendado que lo hagan. + +Las funciones cuyo valor devuelto es el resultado real de un c=C3=A1lculo,= en +lugar de una indicaci=C3=B3n de si el c=C3=B3mputo tuvo =C3=A9xito, no est= =C3=A1n sujetas a +esta regla. Generalmente indican fallo al devolver valores fuera del rango +de resultados. Los ejemplos t=C3=ADpicos ser=C3=ADan funciones que devuelv= en +punteros; estos usan NULL o el mecanismo ERR_PTR para informar de fallos. + +17) Usando bool +---------------- + +El tipo bool del kernel Linux es un alias para el tipo C99 _Bool. Los +valores booleanos pueden solo evaluar a 0 o 1, y la conversi=C3=B3n impl= =C3=ADcita o +expl=C3=ADcita a bool convierte autom=C3=A1ticamente el valor en verdadero= o falso. +Cuando se utilizan tipos booleanos, +!! no se necesita construcci=C3=B3n, lo que elimina una clase de errores. + +Cuando se trabaja con valores booleanos, se deben usar las definiciones +verdadera y falsa, en lugar de 1 y 0. + +Los tipos de devoluci=C3=B3n de funci=C3=B3n bool y las variables de pila = siempre +se pueden usar cuando esto sea adecuado. Se recomienda el uso de bool para +mejorar la legibilidad y, a menudo, es una mejor opci=C3=B3n que 'int' para +almacenar valores booleanos. + +No use bool si el dise=C3=B1o de la l=C3=ADnea de cach=C3=A9 o el tama=C3= =B1o del valor son +importantes, ya que su tama=C3=B1o y la alineaci=C3=B3n var=C3=ADa seg=C3= =BAn la arquitectura +compilada. Las estructuras que son optimizadas para la alineaci=C3=B3n y el +tama=C3=B1o no debe usar bool. + +Si una estructura tiene muchos valores verdadero/falso, considere +consolidarlos en un bitfield con miembros de 1 bit, o usando un tipo de +ancho fijo apropiado, como u8. + +De manera similar, para los argumentos de funci=C3=B3n, se pueden consolid= ar +muchos valores verdaderos/falsos en un solo argumento bit a bit 'flags' y +'flags' a menudo, puede ser una alternativa de argumento m=C3=A1s legible = si los +sitios de llamada tienen constantes desnudas de tipo verdaderas/falsas. + +De lo contrario, el uso limitado de bool en estructuras y argumentos puede +mejorar la legibilidad. + +18) No reinvente las macros del kernel +--------------------------------------- + +El archivo de cabecera include/linux/kernel.h contiene una serie de macros +que debe usar, en lugar de programar expl=C3=ADcitamente alguna variante de +estos por usted mismo. Por ejemplo, si necesita calcular la longitud de una +matriz, aproveche la macro + +.. code-block:: c + + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +De manera similar, si necesita calcular el tama=C3=B1o de alg=C3=BAn miemb= ro de la +estructura, use + +.. code-block:: c + + #define sizeof_field(t, f) (sizeof(((t*)0)->f)) + +Tambi=C3=A9n hay macros min() y max() que realizan una verificaci=C3=B3n e= stricta de +tipos si lo necesita. Si=C3=A9ntase libre de leer detenidamente ese archiv= o de +encabezado para ver qu=C3=A9 m=C3=A1s ya est=C3=A1 definido y que no debe = reproducir en su +c=C3=B3digo. + +19) Editores modeline y otros desastres +--------------------------------------- + +Algunos editores pueden interpretar la informaci=C3=B3n de configuraci=C3= =B3n +incrustada en los archivos fuente, indicado con marcadores especiales. Por +ejemplo, emacs interpreta las l=C3=ADneas marcadas como esto: + +.. code-block:: c + + -*- mode: c -*- + +O as=C3=AD: + +.. code-block:: c + + /* + Local Variables: + compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" + End: + */ + +Vim interpreta los marcadores que se ven as=C3=AD: + +.. code-block:: c + + /* vim:set sw=3D8 noet */ + +No incluya ninguno de estos en los archivos fuente. La gente tiene sus +propias configuraciones del editor, y sus archivos de origen no deben +anularlos. Esto incluye marcadores para sangr=C3=ADa y configuraci=C3=B3n = de modo. +La gente puede usar su propio modo personalizado, o puede tener alg=C3=BAn= otro +m=C3=A9todo m=C3=A1gico para que la sangr=C3=ADa funcione correctamente. + + +20) Ensamblador inline +----------------------- + +En el c=C3=B3digo espec=C3=ADfico de arquitectura, es posible que deba usar +ensamblador en l=C3=ADnea para interactuar con funcionalidades de CPU o +plataforma. No dude en hacerlo cuando sea necesario. Sin embargo, no use +ensamblador en l=C3=ADnea de forma gratuita cuando C puede hacer el trabaj= o. +Puede y debe empujar el hardware desde C cuando sea posible. + +Considere escribir funciones auxiliares simples que envuelvan bits comunes +de ensamblador, en lugar de escribirlos repetidamente con ligeras +variaciones. Recuerde que el ensamblador en l=C3=ADnea puede usar par=C3= =A1metros C. + +Las funciones de ensamblador grandes y no triviales deben ir en archivos .= S, +con su correspondientes prototipos de C definidos en archivos de encabezado +en C. Los prototipos de C para el ensamblador deben usar ``asmlinkage``. + +Es posible que deba marcar su declaraci=C3=B3n asm como vol=C3=A1til, para= evitar que +GCC la elimine si GCC no nota ning=C3=BAn efecto secundario. No siempre es +necesario hacerlo, sin embargo, y hacerlo innecesariamente puede limitar la +optimizaci=C3=B3n. + +Al escribir una sola declaraci=C3=B3n de ensamblador en l=C3=ADnea que con= tiene +m=C3=BAltiples instrucciones, ponga cada instrucci=C3=B3n en una l=C3=ADne= a separada en +una string separada, y termine cada string excepto la =C3=BAltima con ``\n= \t`` +para indentar correctamente la siguiente instrucci=C3=B3n en la salida en +ensamblador: + +.. code-block:: c + + asm ("magic %reg1, #42\n\t" + "more_magic %reg2, %reg3" + : /* outputs */ : /* inputs */ : /* clobbers */); + +21) Compilaci=C3=B3n condicional +--------------------------- + +Siempre que sea posible, no use condicionales de preprocesador (#if, +#ifdef) en archivos .c; de lo contrario, el c=C3=B3digo es m=C3=A1s dif=C3= =ADcil de leer y +la l=C3=B3gica m=C3=A1s dif=C3=ADcil de seguir. En cambio, use dichos cond= icionales en un +archivo de encabezado que defina funciones para usar en esos archivos .c, +proporcionando versiones de c=C3=B3digo auxiliar sin operaci=C3=B3n en el = caso #else, +y luego llame a estas funciones incondicionalmente desde archivos .c. El +compilador evitar=C3=A1 generar cualquier c=C3=B3digo para las llamadas re= stantes, +produciendo resultados id=C3=A9nticos, pero la l=C3=B3gica es f=C3=A1cil d= e seguir. + +Prefiera compilar funciones completas, en lugar de porciones de funciones o +porciones de expresiones. En lugar de poner un ifdef en una expresi=C3=B3n, +divida la totalidad de la expresi=C3=B3n con una funci=C3=B3n de ayuda ind= ependiente +y aplique el condicional a esa funci=C3=B3n. + +Si tiene una funci=C3=B3n o variable que puede potencialmente quedar sin u= sar en +una configuraci=C3=B3n en particular, y el compilador advertir=C3=ADa sobr= e su +definici=C3=B3n sin usar, marque la definici=C3=B3n como __maybe_unused en= lugar de +envolverla en un preprocesador condicional. (Sin embargo, si una funci=C3= =B3n o +variable *siempre* acaba sin ser usada, b=C3=B3rrela.) + +Dentro del c=C3=B3digo, cuando sea posible, use la macro IS_ENABLED para +convertir un s=C3=ADmbolo Kconfig en una expresi=C3=B3n booleana de C, y u= til=C3=ADcelo en +un condicional de C normal: + +.. code-block:: c + + if (IS_ENABLED(CONFIG_SOMETHING)) { + ... + } + +El compilador "doblar=C3=A1"" constantemente el condicional e incluir=C3= =A1 o +excluir=C3=A1 el bloque de c=C3=B3digo al igual que con un #ifdef, por lo = que esto no +agregar=C3=A1 ning=C3=BAn tiempo de gastos generales en ejecuci=C3=B3n. Si= n embargo, este +enfoque todav=C3=ADa permite que el compilador de C vea el c=C3=B3digo den= tro del +bloque, y verifique que sea correcto (sintaxis, tipos, s=C3=ADmbolo, refer= encias, +etc.). Por lo tanto, a=C3=BAn debe usar un #ifdef si el c=C3=B3digo dentro= del bloque +hace referencia a s=C3=ADmbolos que no existir=C3=A1n si no se cumple la c= ondici=C3=B3n. + +Al final de cualquier bloque #if o #ifdef no trivial (m=C3=A1s de unas poc= as +l=C3=ADneas), incluya un comentario despu=C3=A9s de #endif en la misma l= =C3=ADnea, +anotando la expresi=C3=B3n condicional utilizada. Por ejemplo: + +.. code-block:: c + + #ifdef CONFIG_SOMETHING + ... + #endif /* CONFIG_SOMETHING */ + +22) No rompa el kernel +----------------------- + +En general, la decisi=C3=B3n de romper el kernel pertenece al usuario, m= =C3=A1s que +al desarrollador del kernel. + +Evite el panic() +**************** + +panic() debe usarse con cuidado y principalmente solo durante el arranque +del sistema. panic() es, por ejemplo, aceptable cuando se queda sin memoria +durante el arranque y no puede continuar. + +Use WARN() en lugar de BUG() +**************************** + +No agregue c=C3=B3digo nuevo que use cualquiera de las variantes BUG(), co= mo +BUG(), BUG_ON() o VM_BUG_ON(). En su lugar, use una variante WARN*(), +preferiblemente WARN_ON_ONCE(), y posiblemente con c=C3=B3digo de recupera= ci=C3=B3n. +El c=C3=B3digo de recuperaci=C3=B3n no es requerido si no hay una forma ra= zonable de +recuperar, al menos parcialmente. + +"Soy demasiado perezoso para tener en cuenta los errores" no es una excusa +para usar BUG(). Importantes corrupciones internas sin forma de continuar +a=C3=BAn pueden usar BUG(), pero necesitan una buena justificaci=C3=B3n. + +Use WARN_ON_ONCE() en lugar de WARN() o WARN_ON() +************************************************* + +Generalmente, se prefiere WARN_ON_ONCE() a WARN() o WARN_ON(), porque es +com=C3=BAn que una condici=C3=B3n de advertencia dada, si ocurre, ocurra v= arias +veces. Esto puede llenar el registro del kernel, e incluso puede ralentizar +el sistema lo suficiente como para que el registro excesivo se convierta en +su propio, adicional problema. + +No haga WARN a la ligera +************************ + +WARN*() est=C3=A1 dise=C3=B1ado para situaciones inesperadas que nunca deb= er=C3=ADan +suceder. Las macros WARN*() no deben usarse para nada que se espera que +suceda durante un funcionamiento normal. No hay "checkeos" previos o +posteriores a la condici=C3=B3n, por ejemplo. De nuevo: WARN*() no debe us= arse +para una condici=C3=B3n esperada que vaya a activarse f=C3=A1cilmente, por= ejemplo, +mediante acciones en el espacio del usuario. pr_warn_once() es una +alternativa posible, si necesita notificar al usuario de un problema. + +No se preocupe sobre panic_on_warn de usuarios +********************************************** + +Algunas palabras m=C3=A1s sobre panic_on_warn: Recuerde que ``panic_on_war= n`` es +una opci=C3=B3n disponible del kernel, y que muchos usuarios configuran es= ta +opci=C3=B3n. Esta es la raz=C3=B3n por la que hay un art=C3=ADculo de "No = haga WARN a la +ligera", arriba. Sin embargo, la existencia de panic_on_warn de usuarios no +es una raz=C3=B3n v=C3=A1lida para evitar el uso juicioso de WARN*(). Esto= se debe a +que quien habilita panic_on_warn, expl=C3=ADcitamente pidi=C3=B3 al kernel= que +fallara si se dispara un WARN*(), y tales usuarios deben estar preparados +para afrontar las consecuencias de un sistema que es algo m=C3=A1s probabl= e que +se rompa. + +Use BUILD_BUG_ON() para aserciones en tiempo de compilaci=C3=B3n +*********************************************************** + +El uso de BUILD_BUG_ON() es aceptable y recomendado, porque es una aserci= =C3=B3n +en tiempo de compilaci=C3=B3n, que no tiene efecto en tiempo de ejecuci=C3= =B3n. + +Ap=C3=A9ndice I) Referencias +----------------------- + +The C Programming Language, Segunda edicion +por 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 +por Brian W. Kernighan and Rob Pike. +Addison-Wesley, Inc., 1999. +ISBN 0-201-61586-X. + +manuales GCC - en cumplimiento con K&R y este texto - para cpp, gcc, +detalles de gcc y sangr=C3=ADa, todo disponible en https://www.gnu.org/man= ual/ + +WG14 es el grupo de trabajo de estandarizaci=C3=B3n internacional de la +programaci=C3=B3n en lenguaje C, URL: http://www.open-std.org/JTC1/SC22/WG= 14/ + +:ref:`process/coding-style.rst ` del kernel, por greg@kroah.c= om at OLS 2002: +http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ diff --git a/Documentation/translations/sp_SP/process/index.rst b/Documenta= tion/translations/sp_SP/process/index.rst index 4acb7f5005af..49a05f6a5544 100644 --- a/Documentation/translations/sp_SP/process/index.rst +++ b/Documentation/translations/sp_SP/process/index.rst @@ -12,3 +12,4 @@ =20 submitting-patches kernel-docs + coding-style --=20 2.34.1