star-style

Writing conventions for co-authors
Log | Files | Refs | README | LICENSE

star-c.7 (40476B)


      1 .\" Copyright (C)  2026  |Méso|Star> (contact@meso-star.com)
      2 .\"
      3 .\" Ce fichier fait partie de Star-Style
      4 .\"
      5 .\" Star-Style est un logiciel libre ; vous pouvez le redistribuer ou le
      6 .\" modifier suivant les termes de la GNU General Public License telle
      7 .\" que publiée par la Free Software Foundation ; soit la version 3 de
      8 .\" la licence, soit (à votre gré) toute version ultérieure.
      9 .\"
     10 .\" Star-Style est distribué dans l'espoir qu'il sera utile, mais SANS
     11 .\" AUCUNE GARANTIE ; sans même la garantie tacite de QUALITÉ MARCHANDE
     12 .\" ou d'ADÉQUATION à UN BUT PARTICULIER. Consultez la GNU General
     13 .\" Public License pour plus de détails.
     14 .\"
     15 .\" Vous devez avoir reçu une copie de la GNU General Public License en
     16 .\" même temps que Star-Style ; si ce n'est pas le cas, consultez
     17 .\" <http://www.gnu.org/licenses>.
     18 .Dd July 13, 2026
     19 .Dt STAR-C 7
     20 .Os
     21 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
     22 .Sh NOM
     23 .Nm star-c
     24 .Nd guide d'écriture de code en C
     25 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
     26 .Sh DESCRIPTION
     27 Ce document décrit les conventions d'écriture des programmes C
     28 distribués par |Méso|Star>.
     29 Ces recommandations sont données à titre indicatif, et reste
     30 subordonnées aux pratiques effectivement retenues dans chaque
     31 projet ; le plus important étant d'en conserver la cohérence.
     32 Si bien que s'il appartient aux co-auteurs d'un projet de prendre
     33 certaines libertés quant à ce guide de style, toute participation à son
     34 développement devra alors s'efforcer de respecter le style d'écriture du
     35 projet, avant les préférences listées ici.
     36 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
     37 .Sh LE CONTENU D'UN PROJET
     38 En suivant le philosophie UNIX, assurer un jeu de
     39 fonctionnalités par programme aussi ramassé que possible de
     40 sorte à ce que sa mise en oeuvre et son interface restent
     41 simples et ciselées.
     42 L'objet étant d'assurer sa robustesse, son efficacité et sa
     43 modularité qui dépendent d'abord de sa
     44 .Em relation
     45 à un écosystème logiciel qui le dépasse, bien avant son catalogue de
     46 fonctionnalités ou ses prouesses de mise en oeuvre.
     47 .Pp
     48 Le périmètre étroit de chaque programme se retrouve dès lors dans la
     49 structure du projet auquel il appartient, dont le contenu est alors
     50 simple et peu hiérarchisé car comptant en définitive peu de fichiers.
     51 .Pp
     52 La structure type du répertoire d'un projet est :
     53 .Bd -literal -offset Ds
     54 README.md
     55 COPYING
     56 config.mk
     57 Makefile
     58 src/foo.h
     59 src/foo.c
     60 src/foo_bar.c
     61 doc/foo_bar.1
     62 doc/foo.3
     63 .Ed
     64 .Pp
     65 Avec :
     66 .Bl -dash -compact
     67 .It
     68 .Pa README.md
     69 le fichier qui donne le premier niveau d'informations sur le projet ;
     70 .It
     71 .Pa COPYING
     72 la license du projet qui liste ses conditions légales d'utilisation ;
     73 .It
     74 .Pa config.mk
     75 et
     76 .Pa Makefile
     77 les fichiers du système de génération automatique ;
     78 .It
     79 .Pa src/
     80 le répertoire qui contient les codes source du projet ;
     81 .It
     82 .Pa doc/
     83 le répertoire qui stocke sa documentation.
     84 .El
     85 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
     86 .Sh LE LANGAGE C
     87 Utiliser le langage
     88 .Em C89
     89 .Pq ANSI X3.159-1989
     90 aussi appelé C90
     91 .Pq ISO/IEC 9899:1990 ,
     92 les deux étant équivalent.
     93 .Pp
     94 Cette norme est plus épurée que celle qui lui succède à savoir le C99
     95 .Pq ISO SO/IEC 9899:1999 ,
     96 ce qui en fait un dialecte C à la fois plus simple, plus portable et
     97 plus consistant.
     98 Par exemple en ne proposant qu'une seule façon d'écrire les commentaires,
     99 et en interdisant de mélanger du code avec la définition de variables.
    100 .\""""""""""""""""""""""""""""""""""
    101 .Ss Le standard POSIX
    102 Ajouter le support du standard POSIX pour les seuls fichiers qui en ont
    103 besoin, pour notamment pouvoir utiliser des fonctions de la bibliothèque
    104 C standard sinon indisponibles via la seule norme du langage retenue.
    105 .Pp
    106 Pour ce faire, définir la macro
    107 .Sy _POSIX_C_SOURCE
    108 tout en haut du fichier C concerné, avant la moindre directive
    109 d'inclusion.
    110 Par exemple, pour utiliser le standard POSIX.1-2001 :
    111 .Bd -literal -offset Ds
    112 #define _POSIX_C_SOURCE 200112L
    113 .Ed
    114 .Pp
    115 Sous GNU/Linux, se référer à
    116 .Xr feature_test_macros 7
    117 pour une description exhaustive des macros utilisées pour activer le jeu
    118 de fonctionnalités d'un standard donné.
    119 .Pp
    120 L'utilisation d'un C enrichi du standard POSIX n'est ainsi utilisé que
    121 sur les seuls fichiers qui en explicite le besoin ; le C89 restant le
    122 langage utilisé partout ailleurs.
    123 Dans un même souci de portabilité, retenir la première version du
    124 standard POSIX à partir de laquelle la fonctionnalité recherchée est
    125 apparue.
    126 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    127 .Sh LA STRUCTURE D'UN FICHIER SOURCE
    128 Suivre une seule et même structure pour tous les fichiers
    129 sources, qu'ils soient des fichiers d'en-tête
    130 .Pq fichiers Ql *.h
    131 ou des unités de compilation
    132 .Pq fichiers Ql *.c .
    133 Un seul schéma de lecture participant à la clarté du code source.
    134 .Pp
    135 Ci-après sont listées les différentes parties d'un fichier source :
    136 .Bl -enum
    137 .\""""""""""""""""""""""""""""""""""
    138 .It
    139 Un commentaire avec l'avis de copyright et les avis de licence du
    140 programme
    141 .Pq section Sx L'AVIS DE COPYRIGHT ET LES AVIS DE LICENCE Ns
    142  ;
    143 .\""""""""""""""""""""""""""""""""""
    144 .It
    145 La définition d'une macro qui ajoute au langage C du fichier le support
    146 d'un standard POSIX
    147 .Pq section Sx LE LANGAGE C Ns
    148  ;
    149 .\""""""""""""""""""""""""""""""""""
    150 .It
    151 Pour un fichier d'en-tête, l'ouverture d'un garde-fou évitant sa double
    152 inclusion.
    153 Il est fermé en toute fin du fichier
    154 .Pq partie 10 Ns
    155  :
    156 .Bd -literal -offset Ds
    157 #ifndef FOO_H
    158 #define FOO_H
    159 .Ed
    160 .Pp
    161 Le nom de la macro testée puis définie est celui du fichier d'en-tête,
    162 suffixé par
    163 .Ql _H
    164 en référence à l'extension
    165 .Ql .h
    166 du fichier.
    167 Dans l'exemple qui précède, le garde-fou concerne donc le fichier
    168 .In foo.h .
    169 La convention de nommage est sinon celle utilisée pour n'importe quelle
    170 macro
    171 .Pq section Sx LE NOMMAGE .
    172 .\""""""""""""""""""""""""""""""""""
    173 .It
    174 L'inclusion des fichiers d'en-tête requis par le fichier source ;
    175 .Pq section Sx LES FICHIERS D'EN-TÊTE Ns
    176  ;
    177 .\""""""""""""""""""""""""""""""""""
    178 .It
    179 La définition des macros
    180 .Pq section Sx LES MACROS Ns
    181  ;
    182 .\""""""""""""""""""""""""""""""""""
    183 .It
    184 La déclaration anticipée des types structurés :
    185 .Bd -literal -offset Ds
    186 /* Type structurés externes au programme */
    187 struct plugh;
    188 struct quux;
    189 struct xyzzy;
    190 
    191 /* Types structurés définis ailleurs dans le programme */
    192 struct bar;
    193 struct foo;
    194 .Ed
    195 .\""""""""""""""""""""""""""""""""""
    196 .It
    197 La définition des constantes symboliques de type
    198 .Vt enum
    199 .Pq section Sx LES CONSTANTES SYMBOLIQUES Ns
    200  ;
    201 .\""""""""""""""""""""""""""""""""""
    202 .It
    203 La définition des types structurés et de leur(s) constante(s)
    204 .Pq section Sx LES STRUCTURES Ns
    205  ;
    206 .\""""""""""""""""""""""""""""""""""
    207 .It
    208 La déclaration et définition des fonctions
    209 .Pq section Sx LES FONCTIONS .
    210 Dans l'ordre qui suit :
    211 .Pp
    212 .Bl -tag -compact -width a.
    213 .It a.
    214 la déclaration des fonctions ;
    215 .It b.
    216 la définition des fonctions statiques ;
    217 .It c.
    218 pour les unités de compilation, la définition des fonctions.
    219 .El
    220 .\""""""""""""""""""""""""""""""""""
    221 .It
    222 Pour les fichiers d'en-tête, la fin du garde-fou ouvert en 3 pour éviter
    223 la double inclusion du contenu du fichier.
    224 .El
    225 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    226 .Sh LA LONGUEUR DES LIGNES
    227 La longueur maximale recommandée pour une ligne est de
    228 .Em 80
    229 caractères.
    230 .Pp
    231 Ce nombre, standardisé par les cartes perforées et les terminaux des
    232 années 1970, vise aussi à faciliter la lecture du code source en
    233 s'insipirant des conventions d'édition.
    234 Pour un texte imprimé avec une taille de police entre 9 à 12 points et
    235 un inter-ligne d'un caractère, un confort de lecture est assuré dès
    236 lors que chaque ligne compte entre 60 et 75 caractères.
    237 Une proximité avec les 80 caractères retenus, que l'indentation
    238 des sources vient encore renforcer.
    239 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    240 .Sh L'AVIS DE COPYRIGHT ET LES AVIS DE LICENCE
    241 Utiliser la licence libre GPLv3+ qui, en tant que licence copyleft,
    242 défend la copie, l'étude et la modification libres du programme ainsi
    243 licencié, et de ses évolutions.
    244 .Pp
    245 Ajouter une copie de la licence à la racine du projet, dans un fichier
    246 texte nommé
    247 .Pa COPYING
    248 .Pq voir Lk https://www.gnu.org/licenses/gpl-3.0.txt .
    249 .Pp
    250 Lister en commentaire l'avis de copyright et la déclaration
    251 d'autorisation de copie en en-tête de
    252 .Em chaque
    253 fichier source.
    254 .Pp
    255 Chaque copyright débute par le mot
    256 .Ql Copyright ,
    257 en anglais, suivi des 3 caractères
    258 .Ql (C) ,
    259 traduction ASCII du caractère © qui, quant à lui, peut ne pas être
    260 supporté par les jeu de caractères utilisé.
    261 Lister ensuite les années pour lesquelles une version du programme a été
    262 publiée, avant le nom de l'auteur(e) ayant participé(e) à
    263 sa réalisation.
    264 Conclure chaque avis par l'adresse de contact de l'auteur(e), donnée
    265 entre parenthèses.
    266 .Pp
    267 Sauter une ligne après l'avis de copyright et ajouter la déclaration
    268 autorisant la copie telle que donnée par la Fondation pour le logiciel
    269 libre.
    270 Utiliser l'avis de copyright en anglais qui, au contraire de sa
    271 traduction française, revêt une signification juridique.
    272 .Pp
    273 L'en-tête type d'un fichier source du programme
    274 .Ql Foo
    275 est :
    276 .Bd -literal -offset Ds
    277 /* Copyright (C) 2016-2018, 2020, 2022, 2026
    278  *   Jeanne Lambda (jeanne.lambda@courriel.fr)
    279  * Copyright (C) 2017, 2019 Jean Untel (juntel@courriel.fr)
    280  * Copyright (C) 2024 |Méso|Star> (contact@meso-star.com)
    281  *
    282  * This file is part of Foo.
    283  *
    284  * Foo is free software: you can redistribute it and/or
    285  * modify it under the terms of the GNU General Public License
    286  * as published by the Free Software Foundation, either
    287  * version 3 of the License, or (at your option) any later
    288  * version.
    289  *
    290  * Foo is distributed in the hope that it will be useful,
    291  * but WITHOUT ANY WARRANTY; without even the implied warranty
    292  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
    293  * the GNU General Public License for more details.
    294  *
    295  * You should have received a copy of the GNU General Public
    296  * License along with Foo. If not, see
    297  * <https://www.gnu.org/licenses/>. */
    298 .Ed
    299 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    300 .Sh L'INDENTATION
    301 Indenter le texte par 2 espaces.
    302 La mise en page du texte, taille de ligne comprise, est ce faisant
    303 indépendante de la taille d'une tabulation.
    304 .Pp
    305 Les auteurs sont encouragés à configurer leur éditeur pour
    306 qu'il développe chaque caractère tabulation en 2 espaces
    307 .Pq section Sx FICHIERS .
    308 Et ainsi continuer à utiliser la touche tabulation pour l'indentation.
    309 .Pp
    310 Limiter l'indentation à 2 caractères, contre 8 pour le standard de facto
    311 des tabulations, laisse plus d'espace aux différents niveaux
    312 d'indentation, dès lors moins contraints par la limite du nombre de
    313 caractères par ligne
    314 .Pq section Sx LA LONGUEUR DES LIGNES .
    315 Néanmoins, un niveau d'indentation supérieur à 3 est aussi le signe d'un
    316 déficit de structure dans l'écriture du programme.
    317 Les 2 espaces retenus pour indenter le code n'est donc pas une
    318 incitation à aller au delà de 3 niveaux d'indentation sous prétexte de
    319 disposer de plus d'espace par niveau.
    320 .Pp
    321 Indenter le contenu de chaque bloc
    322 .Pq section Sx LES BLOCS .
    323 Pour la directive
    324 .Ql switch ,
    325 indenter chaque
    326 .Ql case
    327 ainsi que leur contenu :
    328 .Bd -literal -offset Ds
    329 switch (opt) {
    330   case 'e':
    331     errno = 0;
    332     epsilon = strtod(optarg, NULL);
    333     if (errno != 0) err = 1;
    334     break;
    335   case 'h':
    336     printf("usage: foo [-hov]\en");
    337     break;
    338   case 'o':
    339     output = optarg;
    340     break;
    341   case 'v':
    342     verbose += (verbose < 3);
    343     break;
    344   default:
    345     err = 1;
    346     break;
    347 }
    348 .Ed
    349 .Pp
    350 Motiver l'utilisation de plusieurs instructions par ligne par
    351 l'expressivité du code en résultant, qu'une écriture resserrée viendrait
    352 renforcer :
    353 .Bd -literal -offset Ds
    354 if (x == NULL || y == NULL) { err = 1; goto error; }
    355 x[0] = 1.0; x[1] = 0.0;
    356 y[0] = 0.0; y[1] = 1.0;
    357 .Ed
    358 .Pp
    359 Ne sauter au plus qu'une ligne.
    360 Ne pas laisser d'espace en fin de ligne et supprimer les lignes vides
    361 en fin de fichier.
    362 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    363 .Sh LES COMMENTAIRES
    364 Utiliser des commentaires dès lors que la seule expressivité serrée du
    365 code ne permet pas d'exprimer l'entièreté du discours que les sources
    366 doivent rendre compte, ou la logique qu'il met effectivement en oeuvre.
    367 .Pp
    368 Si un commentaire occupe plusieurs lignes, ajouter un caractère
    369 .Ql *
    370 en début de ligne, aligné avec le caractère
    371 .Ql *
    372 de la ligne qui précède :
    373 .Bd -literal -offset Ds
    374 /* Valeurs de hachage initiales, à savoir les 32 premiers bits
    375  * de la partie fractionnaire des racines carrées des 4 premiers
    376  * nombres premiers (2, 3, 5 et 7) */
    377 state[0] = 0x6a09e667;
    378 state[1] = 0xbb67ae85;
    379 state[2] = 0x3c6ef372;
    380 state[3] = 0xa54ff53a;
    381 .Ed
    382 .Pp
    383 Les commentaires servent aussi à structurer la lecture du code source.
    384 Que ce soit à l'échelle des instructions, par un commentaire
    385 .Dq chapeau
    386 qui résume la séquence de code qui suit :
    387 .Bd -literal -offset Ds
    388 /* Enregistrer le résultat */
    389 ((uint32_t*)hash)[0] = big_endian_32(state[0]);
    390 ((uint32_t*)hash)[1] = big_endian_32(state[1]);
    391 ((uint32_t*)hash)[2] = big_endian_32(state[2]);
    392 ((uint32_t*)hash)[3] = big_endian_32(state[3]);
    393 .Ed
    394 .Pp
    395 ou à l'échelle du fichier, où les commentaires servent alors de
    396 séparateur entre ses différentes sections
    397 .Pq voir Sx LA STRUCTURE D'UN FICHIER SOURCE .
    398 Dans ce cas, encadrer le commentaire par deux ligne de caractères
    399 .Ql *
    400 qui débute ou se termine par le caractère
    401 .Ql /
    402 si, respectivement, la ligne précède ou suit l'intitulé de la section :
    403 .Bd -literal -offset Ds
    404 /***********************************************************
    405  * Définition des fonctions utilitaires
    406  **********************************************************/
    407 static void
    408 foo(uint32_t bar[4], const char baz[64])
    409 {
    410   ...
    411 }
    412 .Ed
    413 .Pp
    414 À noter que dans l'exemple qui précède, la taille des lignes
    415 d'encadrement est limitée par des contraintes d'édition de la présente
    416 page de manuel.
    417 Dans un fichier source, étendre ces lignes pour qu'elles occupent la
    418 longueur maximale recommandée pour une ligne, à savoir 80 caractères.
    419 .Pp
    420 Pour expliciter le contexte général d'un fichier, en terme d'utilisation
    421 ou d'architecture logicielle, insérer un commentaire en en-tête du
    422 fichier en laissant les caractères d'ouverture ou de fermeture de
    423 commentaires sur une ligne séparée :
    424 .Bd -literal -offset Ds
    425 /*
    426  * Interface de programmation des tableaux extensibles.
    427  * Cette structure de données peut être utilisée avec des
    428  * types de données qui ne nécessitent pas de processus
    429  * d'initialisation ou de libération et qui peuvent être
    430  * copiés bit à bit
    431  */
    432 .Ed
    433 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    434 .Sh LES FICHIERS D'EN-TÊTE
    435 Inclure les fichiers d'en-tête dans l'ordre qui suit :
    436 .Bl -enum -compact
    437 .It
    438 les en-têtes locaux au programme ;
    439 .It
    440 les en-têtes des dépendances du programme ;
    441 .It
    442 les en-têtes systèmes et ceux de la bibliothèque C standard.
    443 .El
    444 .Pp
    445 Les fichiers d'en-tête sont ainsi inclus dans l'ordre décroissant de
    446 leur niveau d'abstraction.
    447 Cet ordre participe à garantir que chaque fichier d'en-tête inclus les
    448 en-têtes dont il a lui même besoin, indépendamment des directives
    449 d'inclusion qui précèdent sa propre inclusion.
    450 Si ce n'est pas le cas, la compilation pourra échouer, symptôme qu'un
    451 des fichiers d'en-tête n'est pas auto-consistant.
    452 .Pp
    453 Dans chaque groupe, trier les directives d'inclusion par ordre
    454 alphabétique des fichiers d'en-tête.
    455 Si besoin, ajouter un commentaire court, sur la même ligne que la
    456 directive d'inclusion, qui explicite la raison pour laquelle la fichier
    457 est inclus.
    458 .Bd -literal -offset Ds
    459 #include "bar.h"
    460 #include "foo.h"
    461 #include "qux.h"
    462 
    463 #include <baz.h>
    464 
    465 #include <float.h> /* FLT_MAX */
    466 #include <stdio.h>
    467 .Ed
    468 .Pp
    469 S'efforcer de n'inclure que les seuls fichiers d'en-tête
    470 réellement nécessaires au fichier ;
    471 par exemple par une déclaration anticipée des types structurés à
    472 la place d'inclure des en-têtes dans le seul but de déclarer lesdits
    473 types.
    474 Un enjeu a considérer avec d'autant plus d'attention que le fichier
    475 concerné par les inclusions est lui même un fichier d'en-tête, par
    476 conséquent amené à être lui même inclus.
    477 L'objet étant de limiter autant que possible le nombre de fichiers
    478 inclus par unité de compilation, pour limiter les accès disque et ainsi
    479 réduire les temps de compilation.
    480 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    481 .Sh LA VISIBILITÉ DES SYMBOLES
    482 Par défaut, n'exposer aucun symbole
    483 .Po
    484 option
    485 .Fl fvisibility=hidden
    486 du compilateur
    487 .Xr gcc 1
    488 .Pc ,
    489 à l'exception de ceux de l'interface de programmation d'une
    490 bibliothèque.
    491 .\""""""""""""""""""""""""""""""""""
    492 .Ss Les symboles d'interface
    493 Privilégier l'écriture d'un seul fichier d'en-tête pour exposer
    494 l'interface de programmation d'une bibliothèque.
    495 Y définir une macro qui exporte les symboles qu'elle déclare dès lors
    496 que ce fichier d'en-tête est inclus par une unité de compilation de la
    497 bibliothèque.
    498 Et qui se contente d'importer ces mêmes symboles si ce même fichier est
    499 inclus par un programme tiers :
    500 .Bd -literal -offset Ds
    501 #include <rsys/rsys.h>
    502 
    503 #if defined(FOO_SHARED_BUILD)
    504   #define FOO_API extern EXPORT_SYM
    505 else
    506   #define FOO_API extern IMPORT_SYM
    507 #endif
    508 .Ed
    509 .Pp
    510 Avec :
    511 .Bl -dash -compact
    512 .It
    513 .Sy FOO_SHARED_BUILD
    514 une macro définie uniquement à la compilation de la bibliothèque
    515 .Po
    516 option
    517 .Fl DFOO_SHARED_BUILD
    518 du compilateur C
    519 .Pc Ns
    520  ;
    521 .It
    522 .Sy EXPORT_SYM
    523 et
    524 .Sy IMPORT_SYM
    525 des directives définies dans la bibliothèque
    526 .Ql RSys .
    527 Elles enrichissent le langage C d'une gestion explicite de la visibilité
    528 des symboles.
    529 .El
    530 .Pp
    531 Utiliser cette macro à la déclaration des variables et constantes
    532 d'interfaces :
    533 .Bd -literal -offset Ds
    534 /* Variables globales de l'interface de programmation */
    535 FOO_API const struct foo foo_plugh;
    536 FOO_API const struct foo foo_xyzzy;
    537 .Ed
    538 .Pp
    539 Déclarer le prototype des fonctions d'interface entre les directives
    540 .Sy BEGIN_DECLS
    541 et
    542 .Sy END_DECLS ,
    543 elles aussi définies dans la bibliothèque
    544 .Ql RSys
    545 .Pq en-tête In rsys/rsys.h .
    546 Ainsi, le fichier d'en-tête peut être inclus par un programe C++ :
    547 .Bd -literal -offset Ds
    548 BEGIN_DECLS
    549 
    550 FOO_API void
    551 foo_bar
    552   (int i,
    553    int* j);
    554 
    555 FOO_API int
    556 foo_qux
    557   (double d,
    558    int i);
    559 
    560 END_DECLS
    561 .Ed
    562 .\""""""""""""""""""""""""""""""""""
    563 .Ss Les symboles internes partagés
    564 Pour les fichiers d'en-tête internes au programme, utiliser la directive
    565 .Sy LOCAL_SYM ,
    566 définie dans le fichier
    567 .In rsys/rsys.h
    568 de la bibliothèque
    569 .Ql RSys ,
    570 pour déclarer les variables globales et prototypes de fonctions.
    571 Ainsi leur symbole n'est pas exposé à l'extérieur du programme.
    572 .Bd -literal -offset Ds
    573 #include <rsys/rsys.h>
    574 
    575 extern LOCAL_SYM char bar[128];
    576 
    577 extern LOCAL_SYM void
    578 quux
    579   (char* tab,
    580    size_t length);
    581 .Ed
    582 .Pp
    583 Cette directive est redondante si le compilateur est configuré pour
    584 masquer par défaut tous les symboles
    585 .Po
    586 option
    587 .Fl fvisibility=hidden
    588 de
    589 .Xr gcc 1
    590 .Pc .
    591 Utiliser
    592 .Sy LOCAL_SYM
    593 permet néanmoins de s'exonérer de cet a priori, tout en uniformisant
    594 les déclarations des fonctions et variables en explicitant pour chaque
    595 déclaration la visibilité du symbole associé.
    596 .\""""""""""""""""""""""""""""""""""
    597 .Ss Les symboles internes à une unité de compilation
    598 Utiliser le mot clé
    599 .Ql static
    600 pour déclarer des variables, constantes, et fonctions visibles
    601 uniquement au sein d'une unité de compilation.
    602 .Pp
    603 C'est notamment le cas des constantes symboliques structurées :
    604 .Bd -literal -offset Ds
    605 struct foo {
    606   int bar;
    607   int qux;
    608 };
    609 static const struct foo FOO_DEFAULT = {1, 0};
    610 .Ed
    611 .Pp
    612 Mais aussi des fonctions utilitaires, qu'elles soient
    613 propres à un fichier C, ou définies dans un fichier d'en-tête.
    614 .Bd -literal -offset Ds
    615 static void
    616 hello(void)
    617 {
    618   printf("Hello, world!\en");
    619 }
    620 .Ed
    621 .Pp
    622 Ces fonctions peuvent en plus être déclarées avec la directive
    623 .Sy INLINE ,
    624 définie dans l'en-tête
    625 .In rsys/rsys.h
    626 de la bibliothèque
    627 .Ql RSys ,
    628 pour suggérer au compilateur de substituer l'appel de la fonction par le
    629 corps de celle-ci, de sorte à éviter le surcoût de l'appel.
    630 Cette directive est équivalente au mot clé
    631 .Ql inline
    632 du C99, indisponible dans le dialecte C retenu
    633 .Pq section Sx LE LANGAGE C .
    634 .Bd -literal -offset Ds
    635 static INLINE void
    636 foo(void)
    637 {
    638   printf("bar\en");
    639 }
    640 .Ed
    641 .Pp
    642 Limiter la directive
    643 .Sy INLINE
    644 aux fonctions élémentaires, destinées à être appelées fréquemment et
    645 dont le coût de l'appel pourrait alors s'avérer significatif.
    646 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    647 .Sh LES BLOCS
    648 Ouvrir chaque bloc sur la même ligne que la directive qui en est à
    649 l'origine
    650 .Po
    651 .Ql do ,
    652 .Ql enum
    653 .Ql for ,
    654 .Ql if ,
    655 .Ql struct ,
    656 .Ql switch ,
    657 .Ql union ,
    658 .Ql while
    659 .Pc ,
    660 en séparant par un espace la fin de la directive et le caractère
    661 .Ql {
    662 qui marque l'ouverture du bloc :
    663 .Bd -literal -offset Ds
    664 if (foo) {
    665   bar();
    666   qux();
    667 }
    668 .Ed
    669 .Pp
    670 Exception faite des fonctions, ou le bloc associé est ouvert sur la
    671 ligne qui suit :
    672 .Bd -literal -offset Ds
    673 static void
    674 foo(void)
    675 {
    676   printf("bar\en");
    677 }
    678 .Ed
    679 .Pp
    680 Fermer un bloc sur une ligne à part sauf s'il est suivi d'une nouvelle
    681 structure de contrôle associée à la précédente
    682 .Po
    683 .Ql if else ,
    684 .Ql do while
    685 .Pc .
    686 Dans ce cas, ajouter la nouvelle instruction sur la même ligne que celle
    687 utilisée pour fermer le bloc, en la séparant du caractère
    688 .Ql }
    689 par un espace.
    690 .Pp
    691 Aligner la fermeture du bloc à l'indentation de sa directive, ou, dans
    692 le cas de directives qui se suivent, à l'indentation de la première
    693 directive à l'origine des blocs successifs :
    694 .Bd -literal -offset Ds
    695 if (foo) {
    696   bar();
    697 } else {
    698   qux();
    699 }
    700 .Ed
    701 .Pp
    702 Écrire sur une seule ligne une directive et les opérations qu'elle
    703 contrôle que si la clarté du code n'en est pas impactée.
    704 Dans ce cas, l'ouverture et la fermeture du bloc associé se fait sur une
    705 seule et même ligne :
    706 .Bd -literal -offset Ds
    707 if (foo) { bar(); return 0; }
    708 .Ed
    709 .Pp
    710 Ne pas utiliser d'accolades si la structure de contrôle n'est suivie
    711 d'aucune ou d'une seule directive écrite sur la même ligne :
    712 .Bd -literal -offset Ds
    713 while (foo());
    714 
    715 if (bar) return 0;
    716 .Ed
    717 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    718 .Sh LES MOTS CLÉS
    719 Ajouter un espace après chaque structure de contrôle
    720 .Ql if ,
    721 .Ql switch ,
    722 .Ql for
    723 et
    724 .Ql while
    725 pour les différencier des appels de fonctions.
    726 Ne pas ajouter d'espace après l'ouverture et avant la fermeture des
    727 parenthèses qui détourent leur(s) expression(s) :
    728 .Bd -literal -offset Ds
    729 if (i < 10) {
    730   foo(i);
    731 }
    732 .Ed
    733 .Pp
    734 Ajouter un espace après chaque point virgule qui sépare les expressions
    735 d'une boucle
    736 .Ql for
    737 sauf si l'expression qui suit est vide :
    738 .Bd -literal -offset Ds
    739 for (i=0; i<10; foo(i++));
    740 
    741 for (;;) { /* Boucle infinie */
    742   poll();
    743   if(bar) break;
    744 }
    745 .Ed
    746 .Pp
    747 Assimiler l'instruction
    748 .Ql sizeof
    749 à une fonction ; ne pas insérer d'espace entre le mot clé et son
    750 expression entourée de parenthèses :
    751 .Bd -literal -offset Ds
    752 sz = sizeof(int);
    753 .Ed
    754 .\""""""""""""""""""""""""""""""""""
    755 .Ss L'instruction Ql switch
    756 Limiter à quelques lignes le contenu de chaque
    757 .Ql case
    758 d'une instruction
    759 .Ql switch ,
    760 celle-ci devant donner à lire la seule répartition des traitements,
    761 fonction de la valeur que peut prendre l'expression du
    762 .Ql switch .
    763 Et non les traitements eux même, sauf s'ils sont triviaux.
    764 Un
    765 .Ql case
    766 au contenu trop fourni est alors le signe d'un manque de structure dans
    767 l'écriture du programme.
    768 .Pp
    769 Toujours ajouter une instruction
    770 .Ql default
    771 même si l'ensemble des valeurs que pourraient prendre l'expression du
    772 .Ql switch
    773 est censé être couvert par les différents
    774 .Ql case .
    775 C'est notamment le cas quand l'expression est une variable
    776 d'énumération.
    777 Utiliser alors la directive
    778 .Sy FATAL ,
    779 définie par la bibliothèque
    780 .Ql RSys
    781 .Pq en-tête In rsys/rsys.h ,
    782 pour signifier un comportement inattendu.
    783 Et ainsi pouvoir diagnostiquer une erreur dans la valeur de l'expression
    784 du
    785 .Ql switch ,
    786 ou un
    787 .Ql case
    788 manquant :
    789 .Bd -literal -offset Ds
    790 switch (i) {
    791   case FOO: foo(); break;
    792   case BAR: bar(); break;
    793   case QUX: qux = 1; break;
    794   default: FATAL("Unreachable code\en"); break;
    795 }
    796 .Ed
    797 .Pp
    798 Ajouter la directive
    799 .Sy FALLTHROUGH ,
    800 définie dans le fichier d'en-tête
    801 .In rsys/rsys.h
    802 de la bibliothèque
    803 .Ql RSys ,
    804 en fin des instructions
    805 .Ql case
    806 qui s'enchaînent.
    807 L'ajout de cette directive permet d'expliciter que c'est bien le
    808 comportement attendu et non l'oublie d'une instruction
    809 .Ql break ,
    810 en plus d'éviter un possible message d'avertissement à la compilation
    811 .Pq option Fl Wimplicit-fallthrough No de Xr gcc 1 Ns
    812  :
    813 .Bd -literal -offset Ds
    814 switch (c) {
    815   case 'a':
    816     foo = 1;
    817     FALLTHROUGH;
    818   case 'b':
    819     bar = 1;
    820     break;
    821   default:
    822     usage();
    823     break;
    824 }
    825 .Ed
    826 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    827 .Sh LE NOMMAGE
    828 .\""""""""""""""""""""""""""""""""""
    829 .Ss Les variables
    830 Nommer les variables en minuscules.
    831 Utiliser le tiret bas
    832 .Ql _
    833 au titre de séparateur entre les termes utilisés dans le nom des
    834 variables :
    835 .Bd -literal -offset Ds
    836 foo_bar
    837 .Ed
    838 .Pp
    839 Expliciter l'objet d'une variable dans son nom avec d'autant plus de
    840 précision que sa portée est grande.
    841 Une variable locale à un bloc de quelques lignes pourra se contenter
    842 d'un nom abrégé tel que
    843 .Va tmp
    844 pour un résultat temporaire, voire n'être qu'un seul caractère
    845 pour un indice
    846 .Va i
    847 ou un nombre d'éléments
    848 .Va n Ns
    849  ; leur contexte d'utilisation venant préciser ce que leur nom résume.
    850 Ce nom abrégé vient non seulement alléger l'écriture mais aussi en
    851 renforcer l'expressivité.
    852 Par exemple
    853 .Va tableau Ns Bq Va i
    854 reste plus clair que
    855 .Va tableau Ns Bq Va indice .
    856 .Pp
    857 Les variables globales sont au contraire à nommer de sorte à décrire ce
    858 qu'elles représentent, indépendamment de tout contexte d'utilisation,
    859 par construction distant de leur déclaration.
    860 Un compteur d'allocations global à un programme aura donc pour nom
    861 .Va compteur_allocations
    862 plutôt que
    863 .Va cpt_allocs .
    864 .Pp
    865 Pour une variable globale déclarée au niveau de l'interface d'une
    866 bibliothèque, préfixer ladite variable avec l'acronyme de la
    867 bibliothèque.
    868 Un compteur d'allocation global à la bibliothèque
    869 .Ql Foo ,
    870 et déclaré en tant que variable globale de son interface, sera alors
    871 nommé
    872 .Va foo_compteur_allocations .
    873 .\""""""""""""""""""""""""""""""""""
    874 .Ss Les fonctions
    875 Nommer les fonctions avec des caractères alphanumérique en minuscules,
    876 et séparer les termes qui composent leur nom par un tiret bas
    877 .Pq caractère Ql _ .
    878 .Pp
    879 Donner à une fonction un nom d'autant plus explicite que sa portée est
    880 importante.
    881 Une fonction utilitaire pourra se contenter d'un nom abrégé, tel que
    882 .Fn cmp
    883 pour une fonction de comparaison utilisée comme argument d'un appel à
    884 .Xr qsort 3
    885 au sein d'un fichier C.
    886 Là où une fonction partagée entre plusieurs unités de compilation aura
    887 un nom plus expressif, tel que
    888 .Fn compare_bar ,
    889 pour notamment expliciter le type
    890 .Vt struct bar
    891 des variables comparées.
    892 Jusqu'à préfixer le nom de la fonction par l'acronyme de la bibliothèque
    893 quand elle est une fonction d'interface de ladite bibliothèque.
    894 Pour la bibliothèque
    895 .Ql Foo ,
    896 une fonction d'interface sera alors nommée
    897 .Fn foo_compare_bar .
    898 .\""""""""""""""""""""""""""""""""""
    899 .Ss Les déclarations de types
    900 Utiliser des caractères alphanumériques en minuscules pour nommer les
    901 structures, unions et énumérations.
    902 Utiliser le tiret bas
    903 .Ql _
    904 pour séparer les différents termes qui composent leur nom.
    905 .Bd -literal -offset Ds
    906 struct foo {
    907   int bar;
    908   int baz
    909 };
    910 
    911 union foo_bar {
    912   double qux;
    913   int xyzzy;
    914 };
    915 .Ed
    916 .Pp
    917 Utiliser la même convention pour nommer les déclarations typedef.
    918 À l'exception du suffixe
    919 .Ql _T
    920 ajouté au nom de l'identificateur du type, en écho au suffixe
    921 .Ql _t
    922 souvent utilisé pour ce type de déclaration, mais réservé par le
    923 standard POSIX.
    924 .Bd -literal -offset Ds
    925 typedef int foo_T;
    926 typedef char foo_bar_T[256];
    927 .Ed
    928 .Pp
    929 Ne pas utiliser de déclaration typedef sur les structures, unions et
    930 énumérations de sorte à permettre leur déclaration anticipée.
    931 .Pp
    932 Préfixer le nom d'un type par l'acronyme de la bibliothèque dès lors
    933 qu'il est un type déclaré en tant que type de son interface.
    934 Par exemple, un type structuré de l'interface de la bibliothèque
    935 .Ql Foo
    936 sera nommé
    937 .Vt struct foo_mon_type .
    938 .\""""""""""""""""""""""""""""""""""
    939 .Ss Constantes et macros
    940 Utiliser des majuscules pour nommer les constantes symboliques, qu'elles
    941 soient des macros, des constantes énumérées, ou des variables déclarées
    942 comme constantes.
    943 Séparer par un tiret bas
    944 .Ql _
    945 les termes qui composent leur nom :
    946 .Bd -literal -offset Ds
    947 #define FOO_BAR 42
    948 
    949 enum foo {
    950   BAR_BAZ,
    951   QUX
    952 };
    953 
    954 static const enum foo FOO_XYZZY = BAR_BAZ;
    955 .Ed
    956 .Pp
    957 Nommer une constante ou une macro de manière d'autant plus explicite
    958 que sa portée est importante.
    959 Une constante définie localement à une fonction pourra se contenter
    960 d'un nom abrégé, jusqu'à n'être qu'un seul caractère, par exemple pour
    961 un nombre d'éléments constant
    962 .Sy N .
    963 Là où le nom d'une macro ou d'une constante définie dans un fichier
    964 d'en-tête se devra d'être plus explicite, tel que
    965 .Sy NOMBRE_ELEMENTS_MAX .
    966 Et être préfixée par l'acronyme de la bibliothèque si elle est déclarée
    967 comme macro ou constante de son interface.
    968 Par exemple, pour la bibliothèque
    969 .Ql Foo ,
    970 .Sy FOO_NOMBRE_ELEMENTS_MAX .
    971 .Pp
    972 Utiliser la convention typographique dite
    973 .Dq camel case
    974 pour nommer les arguments des macros ;
    975 les termes qui composent leur nom sont séparés par une variation de la
    976 casse typographique.
    977 Un terme débute par une majuscule, suivi de caractères
    978 alphanumériques en minuscule.
    979 .Bd -literal -offset Ds
    980 #define FOO_BAR(FooBar, Qux) ((FooBar) + (Qux))
    981 .Ed
    982 .Pp
    983 Ainsi, les arguments de macros sont différenciés des constantes
    984 symboliques et des variables.
    985 .Pp
    986 À noter que la macro elle même est nommée selon la même convention que
    987 celle utilisée pour les constante symboliques
    988 .Pq en majuscule et un tiret bas pour séparer ses différents termes .
    989 La parenthèse ouvrante, collée au nom de la macro, permettant de
    990 différencier les 2 cas.
    991 .\""""""""""""""""""""""""""""""""""
    992 .Ss Les variables et macros internes
    993 Suffixer par deux tirets bas
    994 .Ql __
    995 les variables membres d'une structure définie publiquement, qui n'ont
    996 cependant une signification qu'en interne des fonctions d'interface de
    997 la structure.
    998 L'enjeu étant de souligner que ces variables ne sont accessibles que par
    999 effet de bord, et ne s'addressent
   1000 .Em pas
   1001 aux utilisatrices et utilisateurs, qui ne devraient donc pas y accéder
   1002 directement :
   1003 .Bd -literal -offset Ds
   1004 struct foo {
   1005   double bar;
   1006   int baz;
   1007   int* qux__; /* Variable interne */
   1008 };
   1009 .Ed
   1010 .Pp
   1011 Utiliser le même suffixe en double tirets bas
   1012 .Ql __
   1013 pour nommer les variables internes à une macro, afin d'éviter de masquer
   1014 les variables définies dans le contexte où la macro est développée :
   1015 .Bd -literal -offset Ds
   1016 #define FOO(Bar, N) { \e
   1017   int i__; \e
   1018   for (i__ = 0; i__ < N; Bar(i__), ++i__); \e
   1019 } (void)0
   1020 .Ed
   1021 .Pp
   1022 Suffixer les macros d'un fichier d'en-tête par deux tirets bas
   1023 .Ql __
   1024 dès lors qu'elles sont propres au fichier d'en-tête, et donc
   1025 vraisemblablement inacessibles au delà :
   1026 .Bd -literal -offset Ds
   1027 #define FOO__(Type, Dim) \e
   1028   struct Type {
   1029     int i[Dim];
   1030     float f[Dim];
   1031   }
   1032 FOO__(bar, 2)
   1033 FOO__(baz, 3);
   1034 FOO__(qux, 4);
   1035 #undef FOO__
   1036 .Ed
   1037 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1038 .Sh LES FONCTIONS
   1039 S'attacher à ce que chaque fonction reste simple et concise, en ne
   1040 s'appliquant à ne lui faire faire qu'une seule chose.
   1041 Ce faisant, le corps d'une fonction devrait être lisible sur un ou deux
   1042 écran, avec comme référence la taille des terminaux telle que
   1043 démocratisée à la fin des années 1970, à savoir 24 lignes.
   1044 .Pp
   1045 Un indice quant à la taille qu'une fonction devrait s'efforcer à avoir
   1046 est donné par ses niveaux d'indentation.
   1047 Plus elle compte de niveaux et plus elle devrait être ramassée.
   1048 De même, un nombre de variables locales supérieur à dix peut être le
   1049 signe d'une fonction trop dense.
   1050 .Pp
   1051 Écrire les directives qui contrôlent la portée d'une fonction et son
   1052 type de retour sur une ligne séparée de son nom.
   1053 L'expression régulière
   1054 .Ql ^nom_de_fonction
   1055 peut ainsi être utilisée pour la recherche d'une fonction dans les
   1056 différents fichiers sources.
   1057 .Pp
   1058 Pour une déclaration, revenir à la ligne avant d'ouvrir la parenthèse de
   1059 la fonction, précédée d'une indentation par rapport au nom de la
   1060 fonction sur la ligne qui précède.
   1061 Puis, lister les arguments de la fonction, en revenant à la ligne après
   1062 chacun d'eux et en les alignant les uns par rapport aux autres.
   1063 Ajouter la parenthèse fermante
   1064 .Ql \&)
   1065 et le point virgule
   1066 .Ql \&;
   1067 sur la ligne du dernier argument, sans espace supplémentaire :
   1068 .Bd -literal -offset Ds
   1069 extern LOCAL_SYM void
   1070 foo_bar
   1071   (struct foo* foo,
   1072    const int qux,
   1073    const float xyzzy);
   1074 .Ed
   1075 .Pp
   1076 Les différentes parties qui composent le profil de la fonction sont
   1077 ainsi identifiables par la seule mise en page de sa déclaration.
   1078 .Pp
   1079 Lors de sa définition, lister les arguments de la fonction sur la même
   1080 ligne que le nom de la fonction, sans ajouter d'espace entre le nom de
   1081 la fonction et sa parenthèse ouvrante.
   1082 Si la liste des arguments dépasse la longueur maximale d'une ligne
   1083 .Pq section Sx LA LONGUEUR DES LIGNES
   1084 lister les arguments comme pour une déclaration :
   1085 .Bd -literal -offset Ds
   1086 void
   1087 foo_bar(struct foo* foo, const int qux, const float xyzzy)
   1088 {
   1089   ...
   1090 }
   1091 .Ed
   1092 .Pp
   1093 Ordonner les arguments d'une fonction comme suit :
   1094 .Bl -enum -compact
   1095 .It
   1096 pour une fonction d'interface, la variable sur laquelle la fonction
   1097 opère ;
   1098 .It
   1099 les données d'entrées ;
   1100 .It
   1101 les données en sortie.
   1102 .El
   1103 .Pp
   1104 Ajouter l'instruction
   1105 .Ql const
   1106 aux variables qui n'ont pas vocation à être modifiées par la fonction.
   1107 Et ce quand bien même leur modification n'aurait aucune conséquence,
   1108 comme pour les variables de données simples, copiées à l'appel de la
   1109 fonction.
   1110 L'objet étant de souligner quelles sont des variables en entrée :
   1111 .Bd -literal -offset Ds
   1112 static void
   1113 foo
   1114   (struct foo* foo,
   1115    constr struct bar* bar,
   1116    const int longueur,
   1117    const int* liste,
   1118    int* resultat);
   1119 
   1120 static INLINE double
   1121 madd(const double a, const double b, const double c)
   1122 {
   1123   return a*b + c;
   1124 }
   1125 .Ed
   1126 .Pp
   1127 Ne passer en copie que les seuls paramètres en entrée de la fonction de
   1128 type primitif
   1129 .Pq Vt char , int , double , No énumération, ... .
   1130 Utiliser un pointeur constant dès lors que le paramètre d'entrée est
   1131 de type structuré, afin d'éviter le surcoût de sa copie à chaque appel de
   1132 fonction ; son occupation mémoire étant a priori plus important
   1133 qu'une donnée simple.
   1134 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1135 .Sh LES VARIABLES
   1136 Limiter le nombre de variables par bloc entre 5 et 10.
   1137 Un nombre de variables trop important peut être le signe d'un manque de
   1138 structure auquel un découpage en sous-fonction(s) pourrait remédier
   1139 .Pq section Sx LES FONCTIONS .
   1140 .Pp
   1141 Initialiser les variables dès leur définition avec sinon une valeur
   1142 valide, au moins une valeur par défaut.
   1143 Et d'ainsi éviter l'utilisation de variables non initialisées.
   1144 D'apparence peu critique pour les variables de type primitif, cette
   1145 initialisation l'est bien plus pour les variables structurées, dont la
   1146 liste des membres peut évoluer, sans que le code appelant n'est
   1147 forcément à s'en soucier dès lors que ses membres sont correctement
   1148 initialisés.
   1149 Si elle existe, utiliser la constante proposée avec la structure pour
   1150 initialiser une variable de ce type.
   1151 .Pq voir section Sx LES CONSTANTES .
   1152 En son absence n'initialiser que le premier membre de la variable ; le
   1153 language C assure alors que les autres membres seront initialisés à 0.
   1154 De même pour un tableau alloué sur la pile, initialiser son premier
   1155 élément suffit à garantir que le reste du tableau sera initialisé à
   1156 zero :
   1157 .Bd -literal -offset Ds
   1158 struct foo foo = FOO_DEFAULT;
   1159 struct bar bar = {0};
   1160 int qux[10] = {0};
   1161 int i = 0;
   1162 .Ed
   1163 .Pp
   1164 Au sein d'une même fonction, définir les variables au plus proche de
   1165 leur utilisation de sorte à ce qu'un contexte resserré participe à les
   1166 caractériser.
   1167 Par exemple, une variable
   1168 .Va i
   1169 utilisée dans un bloc comme variable temporaire, et comme indice
   1170 de boucle dans un autre gagnera en expressivité et en
   1171 robustesse à être définie localement à chaque bloc ;
   1172 les deux variables étant, par construction, non seulement séparées mais
   1173 aussi sans effet de bord de l'une sur l'autre :
   1174 .Bd -literal -offset Ds
   1175 if(foo) {
   1176   const int i = bar();
   1177   if (i > max_i) max_val = i;
   1178   if (i < min_i) min_val = i;
   1179 } else {
   1180   int i = 0;
   1181   for(i = 0; i < N; ++i) qux(i);
   1182 }
   1183 .Ed
   1184 .Pp
   1185 Dans un même bloc, regrouper les définitions des variables dès lors
   1186 qu'elles sont liés sémantiquements :
   1187 .Bd -literal -offset Ds
   1188 /* Tableau à traiter */
   1189 double* liste = NULL;
   1190 int longueur_liste = 0;
   1191 .Ed
   1192 .Pp
   1193 Pour chaque groupe de variable, les définir par ordre décroissant de
   1194 leur occupation mémoire a priori.
   1195 Définir par exemple les variables structurées avant les variables de
   1196 données simples.
   1197 Cette convention s'inspire des contraintes des compilateurs C
   1198 qui, pour garantir l'alignement des données eu égard à leur type,
   1199 peuvent ajouter des octets de remplissage, augmentant ce faisant
   1200 l'espace mémoire occupée par la fonction.
   1201 Un sourcoût marginal qui néanmoins peut s'avérer significatif pour
   1202 des fonctions appeler récursivement.
   1203 Ordonner les variables par ordre décroissant de leur taille mémoire
   1204 tend à limiter le nombre d'octets de remplissage nécessaire, et donc le
   1205 coût mémoire associé.
   1206 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1207 .Sh LES CONSTANTES
   1208 Utiliser une énumération si les constantes à définir sont liées
   1209 sémantiquement, et une macro sinon :
   1210 .Bd -literal -offset Ds
   1211 #define ID_INVALIDE ((unsigned)-1)
   1212 
   1213 enum { X, Y, Z };
   1214 
   1215 enum attribut {
   1216   POSITION,
   1217   NORMALE,
   1218   TEXCOORD
   1219 };
   1220 .Ed
   1221 .Pp
   1222 Pour une énumération qui utilise des valeurs par défaut,
   1223 ajouter si besoin une dernière constante qui définit le nombre de
   1224 constantes valides ;
   1225 sa valeur sera ainsi automatiquement mise à jour à chaque changement de
   1226 l'énumération.
   1227 Une telle constante est utile pour définir la cardinalité d'un tableau,
   1228 comme valeur du dernier indice marquant la fin d'une itération,
   1229 ou encore comme valeur vis à vis de laquelle la validité d'une variable
   1230 du type énumérée peut être vérifiée.
   1231 .Bd -literal -offset Ds
   1232 enum molecule {
   1233   H2O,
   1234   CO2,
   1235   O3,
   1236   N2O,
   1237   CO,
   1238   CH4,
   1239 
   1240   NOMBRE_DE_MOLECULES
   1241 };
   1242 
   1243 /* Vérifier qu'une constante définie une molecule valide */
   1244 #define MOLECULE_EST_VALIDE(Mol) \e
   1245   ((unsigned)(Mol) < NOMBRE_DE_MOLECULES)
   1246 
   1247 static const char* NOM_DES_MOLECULES[NOMBRE_DE_MOLECULES] = {
   1248   "H2O", "CO2", "O3", "N2O", "CO", CH4
   1249 };
   1250 .Ed
   1251 .Pp
   1252 Définir les valeurs par défaut d'une structure à l'aide d'une variable
   1253 constante du type concerné, déclarée en tant que variable statique.
   1254 Et une macro qui liste ses valeurs par défaut, utilisé pour initialiser
   1255 ladite variable :
   1256 .Bd -literal -offset Ds
   1257 struct foo {
   1258   int bar;
   1259   float baz;
   1260 };
   1261 #define FOO_DEFAULT__ {-1,0}
   1262 static const struct foo FOO_DEFAULT = FOO_DEFAULT__;
   1263 .Ed
   1264 .Pp
   1265 N'utiliser la macro que lorsqu'il est impossible d'utiliser la variable
   1266 constante, en l'occurence pour initialiser, dès sa définition, les
   1267 membres d'une variable structurée :
   1268 .Bd -literal -offset Ds
   1269 struct qux {
   1270   struct foo foo;
   1271   double
   1272   int quux;
   1273 };
   1274 #define QUX_DEFAULT__ {FOO_DEFAULT__, 0}
   1275 static const struct qux QUX_DEFAULT = QUX_DEFAULT__;
   1276 .Ed
   1277 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1278 .Sh LES STRUCTURES
   1279 .Sh LES MACROS
   1280 .Sh LES ALLOCATIONS DYNAMIQUES
   1281 .Sh LA GESTION DES ERREURS
   1282 .Sh LES PROGRAMME EN LIGNE DE COMMANDE
   1283 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1284 .Sh FICHIERS
   1285 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1286 .Sh VOIR AUSSI
   1287 .Xr gcc 1 ,
   1288 .Xr feature_test_macros 7
   1289 .Pp
   1290 .Rs
   1291 .%A La Fondation pour le logiciel libre
   1292 .%T Comment utiliser les licences GNU pour vos logiciels
   1293 .%U https://www.gnu.org/licenses/gpl-howto.fr.html
   1294 .Re