star-style

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

star-c.7 (56107B)


      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 October 2, 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 du projet ;
     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 des macros 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 en majuscule, 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 la police de caractères utilisée.
    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 auteures et auteurs sont encouragés à configurer leur éditeur de
    306 texture pour 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 Ajouter un espace après l'ouverture du commentaire
    369 .Ql /*
    370 et avant sa fermeture
    371 .Ql */ .
    372 .Pp
    373 Si un commentaire occupe plusieurs lignes, ajouter un caractère
    374 .Ql *
    375 en début de ligne, aligné avec le caractère
    376 .Ql *
    377 de la ligne qui précède.
    378 Ajouter un espace entre le caractère
    379 .Ql * ,
    380 qui marque la continuation du commentaire, et la suite du commentaire :
    381 .Bd -literal -offset Ds
    382 /* Valeurs de hachage initiales, à savoir les 32 premiers bits
    383  * de la partie fractionnaire des racines carrées des 4 premiers
    384  * nombres premiers (2, 3, 5 et 7) */
    385 state[0] = 0x6a09e667;
    386 state[1] = 0xbb67ae85;
    387 state[2] = 0x3c6ef372;
    388 state[3] = 0xa54ff53a;
    389 .Ed
    390 .Pp
    391 Les commentaires servent aussi à structurer la lecture du code source.
    392 Que ce soit à l'échelle des instructions, par un commentaire
    393 .Dq chapeau
    394 qui résume la séquence de code qui suit :
    395 .Bd -literal -offset Ds
    396 /* Enregistrer le résultat */
    397 ((uint32_t*)hash)[0] = big_endian_32(state[0]);
    398 ((uint32_t*)hash)[1] = big_endian_32(state[1]);
    399 ((uint32_t*)hash)[2] = big_endian_32(state[2]);
    400 ((uint32_t*)hash)[3] = big_endian_32(state[3]);
    401 .Ed
    402 .Pp
    403 ou à l'échelle du fichier, où les commentaires servent alors de
    404 séparateur entre ses différentes sections
    405 .Pq voir Sx LA STRUCTURE D'UN FICHIER SOURCE .
    406 Dans ce cas, encadrer le commentaire par deux ligne de caractères
    407 .Ql *
    408 qui débute ou se termine par le caractère
    409 .Ql /
    410 si, respectivement, la ligne précède ou suit l'intitulé de la section :
    411 .Bd -literal -offset Ds
    412 /***********************************************************
    413  * Définition des fonctions utilitaires
    414  **********************************************************/
    415 static void
    416 foo(uint32_t bar[4], const char baz[64])
    417 {
    418   ...
    419 }
    420 
    421 static int
    422 qux(const int xyzzy)
    423 {
    424   ...
    425 }
    426 .Ed
    427 .Pp
    428 À noter que dans l'exemple qui précède, la taille des lignes
    429 d'encadrement est limitée par des contraintes d'édition de la présente
    430 page de manuel.
    431 Dans un fichier source, étendre ces lignes pour qu'elles occupent la
    432 longueur maximale recommandée pour une ligne
    433 .Pq section Sx LA LONGUEUR DES LIGNES .
    434 .Pp
    435 Pour expliciter le contexte général d'un fichier, en terme d'utilisation
    436 ou d'architecture logicielle, insérer un commentaire en en-tête du
    437 fichier en laissant les caractères d'ouverture ou de fermeture de
    438 commentaires sur une ligne séparée :
    439 .Bd -literal -offset Ds
    440 /*
    441  * Interface de programmation des tableaux extensibles.
    442  * Cette structure de données peut être utilisée avec des
    443  * types de données qui ne nécessitent pas de processus
    444  * d'initialisation ou de libération et qui peuvent être
    445  * copiés bit à bit
    446  */
    447 .Ed
    448 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    449 .Sh LES FICHIERS D'EN-TÊTE
    450 Inclure les fichiers d'en-tête dans l'ordre qui suit :
    451 .Bl -enum -compact
    452 .It
    453 les en-têtes locaux au programme ;
    454 .It
    455 les en-têtes des dépendances du programme ;
    456 .It
    457 les en-têtes systèmes et ceux de la bibliothèque C standard.
    458 .El
    459 .Pp
    460 Les fichiers d'en-tête sont ainsi inclus dans l'ordre décroissant de
    461 leur niveau d'abstraction.
    462 Cet ordre participe à garantir que chaque fichier d'en-tête inclus les
    463 en-têtes dont il a lui même besoin, indépendamment des directives
    464 d'inclusion qui précèdent sa propre inclusion.
    465 Si ce n'est pas le cas, la compilation pourra échouer, symptôme qu'un
    466 des fichiers d'en-tête n'est pas auto-consistant.
    467 .Pp
    468 Dans chaque groupe, trier les directives d'inclusion par ordre
    469 alphabétique des fichiers d'en-tête.
    470 Si besoin, ajouter un commentaire court, sur la même ligne que la
    471 directive d'inclusion, qui explicite la raison pour laquelle la fichier
    472 est inclus.
    473 .Bd -literal -offset Ds
    474 #include "bar.h"
    475 #include "foo.h"
    476 #include "qux.h"
    477 
    478 #include <baz.h>
    479 
    480 #include <float.h> /* FLT_MAX */
    481 #include <stdio.h>
    482 .Ed
    483 .Pp
    484 S'efforcer de n'inclure que les seuls fichiers d'en-tête
    485 réellement nécessaires au fichier ;
    486 par exemple par une déclaration anticipée des types structurés à
    487 la place d'inclure des en-têtes dans le seul but de déclarer lesdits
    488 types.
    489 Un enjeu a considérer avec d'autant plus d'attention que le fichier
    490 concerné par les inclusions est lui même un fichier d'en-tête, par
    491 conséquent amené à être lui même inclus.
    492 L'objet étant de limiter autant que possible le nombre de fichiers
    493 inclus par unité de compilation, pour limiter les accès disque et ainsi
    494 réduire les temps de compilation.
    495 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    496 .Sh LA VISIBILITÉ DES SYMBOLES
    497 Par défaut, n'exposer aucun symbole
    498 .Po
    499 option
    500 .Fl fvisibility=hidden
    501 du compilateur
    502 .Xr gcc 1
    503 .Pc ,
    504 à l'exception de ceux de l'interface de programmation d'une
    505 bibliothèque.
    506 .\""""""""""""""""""""""""""""""""""
    507 .Ss Les symboles d'interface
    508 Privilégier l'écriture d'un seul fichier d'en-tête pour exposer
    509 l'interface de programmation d'une bibliothèque.
    510 Y définir une macro qui exporte les symboles qu'elle déclare dès lors
    511 que ce fichier d'en-tête est inclus par une unité de compilation de la
    512 bibliothèque.
    513 Et qui se contente d'importer ces mêmes symboles si ce même fichier est
    514 inclus par un programme tiers :
    515 .Bd -literal -offset Ds
    516 #include <rsys/rsys.h>
    517 
    518 #if defined(FOO_SHARED_BUILD)
    519   #define FOO_API extern EXPORT_SYM
    520 else
    521   #define FOO_API extern IMPORT_SYM
    522 #endif
    523 .Ed
    524 .Pp
    525 Avec :
    526 .Bl -dash -compact
    527 .It
    528 .Sy FOO_SHARED_BUILD
    529 une macro définie uniquement à la compilation de la bibliothèque
    530 .Po
    531 option
    532 .Fl DFOO_SHARED_BUILD
    533 du compilateur C
    534 .Pc Ns
    535  ;
    536 .It
    537 .Sy EXPORT_SYM
    538 et
    539 .Sy IMPORT_SYM
    540 des directives définies dans la bibliothèque
    541 .Ql RSys .
    542 Elles enrichissent le langage C d'une gestion explicite de la visibilité
    543 des symboles.
    544 .El
    545 .Pp
    546 Utiliser cette macro à la déclaration des variables et constantes
    547 d'interfaces :
    548 .Bd -literal -offset Ds
    549 /* Variables globales de l'interface de programmation */
    550 FOO_API const struct foo foo_plugh;
    551 FOO_API const struct foo foo_xyzzy;
    552 .Ed
    553 .Pp
    554 Déclarer le prototype des fonctions d'interface entre les directives
    555 .Sy BEGIN_DECLS
    556 et
    557 .Sy END_DECLS ,
    558 elles aussi définies dans la bibliothèque
    559 .Ql RSys
    560 .Pq en-tête In rsys/rsys.h .
    561 Ainsi, le fichier d'en-tête peut être inclus par un programe C++ :
    562 .Bd -literal -offset Ds
    563 BEGIN_DECLS
    564 
    565 FOO_API void
    566 foo_bar
    567   (int i,
    568    int* j);
    569 
    570 FOO_API int
    571 foo_qux
    572   (double d,
    573    int i);
    574 
    575 END_DECLS
    576 .Ed
    577 .\""""""""""""""""""""""""""""""""""
    578 .Ss Les symboles internes partagés
    579 Pour les fichiers d'en-tête internes au programme, utiliser la directive
    580 .Sy LOCAL_SYM ,
    581 définie dans le fichier
    582 .In rsys/rsys.h
    583 de la bibliothèque
    584 .Ql RSys ,
    585 pour déclarer les variables globales et prototypes de fonctions.
    586 Ainsi leur symbole n'est pas exposé à l'extérieur du programme.
    587 .Bd -literal -offset Ds
    588 #include <rsys/rsys.h>
    589 
    590 extern LOCAL_SYM char bar[128];
    591 
    592 extern LOCAL_SYM void
    593 quux
    594   (char* tab,
    595    size_t length);
    596 .Ed
    597 .Pp
    598 Cette directive est redondante si le compilateur est configuré pour
    599 masquer par défaut tous les symboles
    600 .Po
    601 option
    602 .Fl fvisibility=hidden
    603 de
    604 .Xr gcc 1
    605 .Pc .
    606 Utiliser
    607 .Sy LOCAL_SYM
    608 permet néanmoins de s'exonérer de cet a priori, tout en uniformisant
    609 les déclarations des fonctions et variables en explicitant pour chaque
    610 déclaration la visibilité du symbole associé.
    611 .\""""""""""""""""""""""""""""""""""
    612 .Ss Les symboles internes à une unité de compilation
    613 Utiliser le mot clé
    614 .Ql static
    615 pour déclarer des variables, constantes, et fonctions visibles
    616 uniquement au sein d'une unité de compilation.
    617 .Pp
    618 C'est notamment le cas des constantes symboliques structurées :
    619 .Bd -literal -offset Ds
    620 struct foo {
    621   int bar;
    622   int qux;
    623 };
    624 static const struct foo FOO_DEFAULT = {1, 0};
    625 .Ed
    626 .Pp
    627 Mais aussi des fonctions utilitaires, qu'elles soient
    628 propres à un fichier C, ou définies dans un fichier d'en-tête.
    629 .Bd -literal -offset Ds
    630 static void
    631 hello(void)
    632 {
    633   printf("Hello, world!\en");
    634 }
    635 .Ed
    636 .Pp
    637 Ces fonctions peuvent en plus être déclarées avec la directive
    638 .Sy INLINE ,
    639 définie dans l'en-tête
    640 .In rsys/rsys.h
    641 de la bibliothèque
    642 .Ql RSys ,
    643 pour suggérer au compilateur de substituer l'appel de la fonction par le
    644 corps de celle-ci, de sorte à éviter le surcoût de l'appel.
    645 Cette directive est équivalente au mot clé
    646 .Ql inline
    647 du C99, indisponible dans le dialecte C retenu
    648 .Pq section Sx LE LANGAGE C .
    649 .Bd -literal -offset Ds
    650 static INLINE void
    651 foo(void)
    652 {
    653   printf("bar\en");
    654 }
    655 .Ed
    656 .Pp
    657 Limiter la directive
    658 .Sy INLINE
    659 aux fonctions élémentaires, destinées à être appelées fréquemment et
    660 dont le coût de l'appel pourrait alors s'avérer significatif.
    661 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    662 .Sh LES BLOCS
    663 Ouvrir chaque bloc sur la même ligne que la directive qui en est à
    664 l'origine
    665 .Po
    666 .Ql do ,
    667 .Ql enum
    668 .Ql for ,
    669 .Ql if ,
    670 .Ql struct ,
    671 .Ql switch ,
    672 .Ql union ,
    673 .Ql while
    674 .Pc ,
    675 en séparant par un espace la fin de la directive et le caractère
    676 .Ql {
    677 qui marque l'ouverture du bloc :
    678 .Bd -literal -offset Ds
    679 if (foo) {
    680   bar();
    681   qux();
    682 }
    683 .Ed
    684 .Pp
    685 Exception faite des fonctions, ou le bloc associé est ouvert sur la
    686 ligne qui suit :
    687 .Bd -literal -offset Ds
    688 static void
    689 foo(void)
    690 {
    691   printf("bar\en");
    692 }
    693 .Ed
    694 .Pp
    695 Fermer un bloc sur une ligne à part sauf s'il est suivi d'une nouvelle
    696 structure de contrôle associée à la précédente
    697 .Po
    698 .Ql if else ,
    699 .Ql do while
    700 .Pc .
    701 Dans ce cas, ajouter la nouvelle instruction sur la même ligne que celle
    702 utilisée pour fermer le bloc, en la séparant du caractère
    703 .Ql }
    704 par un espace.
    705 .Pp
    706 Aligner la fermeture du bloc à l'indentation de sa directive, ou, dans
    707 le cas de directives qui se suivent, à l'indentation de la première
    708 directive à l'origine des blocs successifs :
    709 .Bd -literal -offset Ds
    710 if (foo) {
    711   bar();
    712 } else {
    713   qux();
    714 }
    715 .Ed
    716 .Pp
    717 Écrire sur une seule ligne une directive et les opérations qu'elle
    718 contrôle que si la clarté du code n'en est pas impactée.
    719 Dans ce cas, l'ouverture et la fermeture du bloc associé se fait sur une
    720 seule et même ligne :
    721 .Bd -literal -offset Ds
    722 if (foo) { bar(); return 0; }
    723 .Ed
    724 .Pp
    725 Ne pas utiliser d'accolades si la structure de contrôle n'est suivie
    726 d'aucune ou d'une seule directive écrite sur la même ligne :
    727 .Bd -literal -offset Ds
    728 while (foo());
    729 
    730 if (bar) return 0;
    731 .Ed
    732 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    733 .Sh LES MOTS CLÉS
    734 Ajouter un espace après chaque structure de contrôle
    735 .Ql if ,
    736 .Ql switch ,
    737 .Ql for
    738 et
    739 .Ql while
    740 pour les différencier des appels de fonctions.
    741 Ne pas ajouter d'espace après l'ouverture et avant la fermeture des
    742 parenthèses qui détourent leur(s) expression(s) :
    743 .Bd -literal -offset Ds
    744 if (i < 10) {
    745   foo(i);
    746 }
    747 .Ed
    748 .Pp
    749 Ajouter un espace après chaque point virgule qui sépare les expressions
    750 d'une boucle
    751 .Ql for
    752 sauf si l'expression qui suit est vide :
    753 .Bd -literal -offset Ds
    754 for (i=0; i<10; foo(i++));
    755 
    756 for (;;) { /* Boucle infinie */
    757   poll();
    758   if(bar) break;
    759 }
    760 .Ed
    761 .Pp
    762 Assimiler l'instruction
    763 .Ql sizeof
    764 à une fonction ; ne pas insérer d'espace entre le mot clé et son
    765 expression entourée de parenthèses :
    766 .Bd -literal -offset Ds
    767 sz = sizeof(int);
    768 .Ed
    769 .\""""""""""""""""""""""""""""""""""
    770 .Ss L'instruction Ql switch
    771 Limiter à quelques lignes le contenu de chaque
    772 .Ql case
    773 d'une instruction
    774 .Ql switch ,
    775 celle-ci devant donner à lire la seule répartition des traitements,
    776 fonction de la valeur que peut prendre l'expression du
    777 .Ql switch .
    778 Et non les traitements eux même, sauf s'ils sont triviaux.
    779 Un
    780 .Ql case
    781 au contenu trop fourni est alors le signe d'un manque de structure dans
    782 l'écriture du programme.
    783 .Pp
    784 Toujours ajouter une instruction
    785 .Ql default
    786 même si l'ensemble des valeurs que pourraient prendre l'expression du
    787 .Ql switch
    788 est censé être couvert par les différents
    789 .Ql case .
    790 C'est notamment le cas quand l'expression est une variable
    791 d'énumération.
    792 Utiliser alors la directive
    793 .Sy FATAL ,
    794 définie par la bibliothèque
    795 .Ql RSys
    796 .Pq en-tête In rsys/rsys.h ,
    797 pour signifier un comportement inattendu.
    798 Et ainsi pouvoir diagnostiquer une erreur dans la valeur de l'expression
    799 du
    800 .Ql switch ,
    801 ou un
    802 .Ql case
    803 manquant :
    804 .Bd -literal -offset Ds
    805 switch (i) {
    806   case FOO: foo(); break;
    807   case BAR: bar(); break;
    808   case QUX: qux = 1; break;
    809   default: FATAL("Unreachable code\en"); break;
    810 }
    811 .Ed
    812 .Pp
    813 Ajouter la directive
    814 .Sy FALLTHROUGH ,
    815 définie dans le fichier d'en-tête
    816 .In rsys/rsys.h
    817 de la bibliothèque
    818 .Ql RSys ,
    819 en fin des instructions
    820 .Ql case
    821 qui s'enchaînent.
    822 L'ajout de cette directive permet d'expliciter que c'est bien le
    823 comportement attendu et non l'oublie d'une instruction
    824 .Ql break ,
    825 en plus d'éviter un possible message d'avertissement à la compilation
    826 .Pq option Fl Wimplicit-fallthrough No de Xr gcc 1 Ns
    827  :
    828 .Bd -literal -offset Ds
    829 switch (c) {
    830   case 'a':
    831     foo = 1;
    832     FALLTHROUGH;
    833   case 'b':
    834     bar = 1;
    835     break;
    836   default:
    837     usage();
    838     break;
    839 }
    840 .Ed
    841 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    842 .Sh LE NOMMAGE
    843 .\""""""""""""""""""""""""""""""""""
    844 .Ss Les variables
    845 Nommer les variables en minuscules.
    846 Utiliser le tiret bas
    847 .Ql _
    848 au titre de séparateur entre les termes utilisés dans le nom des
    849 variables :
    850 .Bd -literal -offset Ds
    851 foo_bar
    852 .Ed
    853 .Pp
    854 Expliciter l'objet d'une variable dans son nom avec d'autant plus de
    855 précision que sa portée est grande.
    856 Une variable locale à un bloc de quelques lignes pourra se contenter
    857 d'un nom abrégé tel que
    858 .Va tmp
    859 pour un résultat temporaire, voire n'être qu'un seul caractère
    860 pour un indice
    861 .Va i
    862 ou un nombre d'éléments
    863 .Va n Ns
    864  ; leur contexte d'utilisation venant préciser ce que leur nom résume.
    865 Ce nom abrégé vient non seulement alléger l'écriture mais aussi en
    866 renforcer l'expressivité.
    867 Par exemple
    868 .Va tableau Ns Bq Va i
    869 reste plus clair que
    870 .Va tableau Ns Bq Va indice .
    871 .Pp
    872 Les variables globales sont au contraire à nommer de sorte à décrire ce
    873 qu'elles représentent, indépendamment de tout contexte d'utilisation,
    874 par construction distant de leur déclaration.
    875 Un compteur d'allocations global à un programme aura donc pour nom
    876 .Va compteur_allocations
    877 plutôt que
    878 .Va cpt_allocs .
    879 .Pp
    880 Pour une variable globale déclarée au niveau de l'interface d'une
    881 bibliothèque, préfixer ladite variable avec l'acronyme de la
    882 bibliothèque.
    883 Un compteur d'allocation global à la bibliothèque
    884 .Ql Foo ,
    885 et déclaré en tant que variable globale de son interface, sera alors
    886 nommé
    887 .Va foo_compteur_allocations .
    888 .\""""""""""""""""""""""""""""""""""
    889 .Ss Les fonctions
    890 Nommer les fonctions avec des caractères alphanumérique en minuscules,
    891 et séparer les termes qui composent leur nom par un tiret bas
    892 .Pq caractère Ql _ .
    893 .Pp
    894 Donner à une fonction un nom d'autant plus explicite que sa portée est
    895 importante.
    896 Une fonction utilitaire pourra se contenter d'un nom abrégé, tel que
    897 .Fn cmp
    898 pour une fonction de comparaison utilisée comme argument d'un appel à
    899 .Xr qsort 3
    900 au sein d'un fichier C.
    901 Là où une fonction partagée entre plusieurs unités de compilation aura
    902 un nom plus expressif, tel que
    903 .Fn compare_bar ,
    904 pour notamment expliciter le type
    905 .Vt struct bar
    906 des variables comparées.
    907 Jusqu'à préfixer le nom de la fonction par l'acronyme de la bibliothèque
    908 quand elle est une fonction d'interface de ladite bibliothèque.
    909 Pour la bibliothèque
    910 .Ql Foo ,
    911 une fonction d'interface sera alors nommée
    912 .Fn foo_compare_bar .
    913 .\""""""""""""""""""""""""""""""""""
    914 .Ss Les déclarations de types
    915 Utiliser des caractères alphanumériques en minuscules pour nommer les
    916 structures, unions et énumérations.
    917 Utiliser le tiret bas
    918 .Ql _
    919 pour séparer les différents termes qui composent leur nom.
    920 .Bd -literal -offset Ds
    921 struct foo {
    922   int bar;
    923   int baz
    924 };
    925 
    926 union foo_bar {
    927   double qux;
    928   int xyzzy;
    929 };
    930 .Ed
    931 .Pp
    932 Utiliser la même convention pour nommer les déclarations typedef.
    933 À l'exception du suffixe
    934 .Ql _T
    935 ajouté au nom de l'identificateur du type, en écho au suffixe
    936 .Ql _t
    937 souvent utilisé pour ce type de déclaration, mais réservé par le
    938 standard POSIX.
    939 .Bd -literal -offset Ds
    940 typedef int foo_T;
    941 typedef char foo_bar_T[256];
    942 .Ed
    943 .Pp
    944 Ne pas utiliser de déclaration typedef sur les structures, unions et
    945 énumérations de sorte à permettre leur déclaration anticipée.
    946 .Pp
    947 Préfixer le nom d'un type par l'acronyme de la bibliothèque dès lors
    948 qu'il est un type déclaré en tant que type de son interface.
    949 Par exemple, un type structuré de l'interface de la bibliothèque
    950 .Ql Foo
    951 sera nommé
    952 .Vt struct foo_mon_type .
    953 .\""""""""""""""""""""""""""""""""""
    954 .Ss Constantes et macros
    955 Utiliser des majuscules pour nommer les constantes symboliques, qu'elles
    956 soient des macros, des constantes énumérées, ou des variables déclarées
    957 comme constantes.
    958 Séparer par un tiret bas
    959 .Ql _
    960 les termes qui composent leur nom :
    961 .Bd -literal -offset Ds
    962 #define FOO_BAR 42
    963 
    964 enum foo {
    965   BAR_BAZ,
    966   QUX
    967 };
    968 
    969 static const enum foo FOO_XYZZY = BAR_BAZ;
    970 .Ed
    971 .Pp
    972 Nommer une constante ou une macro de manière d'autant plus explicite
    973 que sa portée est importante.
    974 Une constante définie localement à une fonction pourra se contenter
    975 d'un nom abrégé, jusqu'à n'être qu'un seul caractère, par exemple pour
    976 un nombre d'éléments constant
    977 .Sy N .
    978 Là où le nom d'une macro ou d'une constante définie dans un fichier
    979 d'en-tête se devra d'être plus explicite, tel que
    980 .Sy NOMBRE_ELEMENTS_MAX .
    981 Et être préfixée par l'acronyme de la bibliothèque si elle est déclarée
    982 comme macro ou constante de son interface.
    983 Par exemple, pour la bibliothèque
    984 .Ql Foo ,
    985 .Sy FOO_NOMBRE_ELEMENTS_MAX .
    986 .Pp
    987 Utiliser la convention typographique dite
    988 .Dq camel case
    989 pour nommer les arguments des macros ;
    990 les termes qui composent leur nom sont séparés par une variation de la
    991 casse typographique.
    992 Un terme débute par une majuscule, suivi de caractères
    993 alphanumériques en minuscules.
    994 .Bd -literal -offset Ds
    995 #define FOO_BAR(FooBar, Qux) ((FooBar) + (Qux))
    996 .Ed
    997 .Pp
    998 Ainsi, les arguments de macros sont différenciés des constantes
    999 symboliques et des variables.
   1000 .Pp
   1001 À noter que la macro elle même est nommée selon la même convention que
   1002 celle utilisée pour les constante symboliques
   1003 .Pq en majuscule et un tiret bas pour séparer ses différents termes .
   1004 La parenthèse ouvrante, collée au nom de la macro, permettant de
   1005 différencier les 2 cas.
   1006 .\""""""""""""""""""""""""""""""""""
   1007 .Ss Les variables et macros internes
   1008 Suffixer par deux tirets bas
   1009 .Ql __
   1010 les variables membres d'une structure définie publiquement, qui n'ont
   1011 cependant une signification qu'en interne des fonctions d'interface de
   1012 la structure.
   1013 L'enjeu étant de souligner que ces variables ne sont accessibles que par
   1014 effet de bord, et ne s'addressent
   1015 .Em pas
   1016 aux utilisatrices et utilisateurs, qui ne devraient donc pas y accéder
   1017 directement :
   1018 .Bd -literal -offset Ds
   1019 struct foo {
   1020   double bar;
   1021   int baz;
   1022   int* qux__; /* Variable interne */
   1023 };
   1024 .Ed
   1025 .Pp
   1026 Utiliser le même suffixe en double tirets bas
   1027 .Ql __
   1028 pour nommer les variables internes à une macro, afin d'éviter de masquer
   1029 les variables définies dans le contexte où la macro est développée :
   1030 .Bd -literal -offset Ds
   1031 #define FOO(Bar, N) {                                      \e
   1032   int i__;                                                 \e
   1033   for (i__ = 0; i__ < N; Bar(i__), ++i__);                 \e
   1034 } (void)0
   1035 .Ed
   1036 .Pp
   1037 Suffixer les macros d'un fichier d'en-tête par deux tirets bas
   1038 .Ql __
   1039 dès lors qu'elles sont propres au fichier d'en-tête, et donc
   1040 vraisemblablement inacessibles au delà :
   1041 .Bd -literal -offset Ds
   1042 #define FOO__(Type, Dim)                                   \e
   1043   struct Type {                                            \e
   1044     int i[Dim];                                            \e
   1045     float f[Dim];                                          \e
   1046   }
   1047 FOO__(bar, 2);
   1048 FOO__(baz, 3);
   1049 FOO__(qux, 4);
   1050 #undef FOO__
   1051 .Ed
   1052 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1053 .Sh LES FONCTIONS
   1054 S'attacher à ce que chaque fonction reste simple et concise, en ne
   1055 s'appliquant à ne lui faire faire qu'une seule chose.
   1056 Ce faisant, le corps d'une fonction devrait être lisible sur un ou deux
   1057 écran, avec comme référence la taille des terminaux telle que
   1058 démocratisée à la fin des années 1970, à savoir 24 lignes.
   1059 .Pp
   1060 Un indice quant à la taille qu'une fonction devrait s'efforcer à avoir
   1061 est donné par ses niveaux d'indentation.
   1062 Plus elle compte de niveaux et plus elle devrait être ramassée.
   1063 De même, un nombre de variables locales supérieur à dix peut être le
   1064 signe d'une fonction trop dense.
   1065 .Pp
   1066 Écrire les directives qui contrôlent la portée d'une fonction et son
   1067 type de retour sur une ligne séparée de son nom.
   1068 L'expression régulière
   1069 .Ql ^nom_de_fonction
   1070 peut ainsi être utilisée pour la recherche d'une fonction dans les
   1071 différents fichiers sources.
   1072 .Pp
   1073 Pour une déclaration, revenir à la ligne avant d'ouvrir la parenthèse de
   1074 la fonction, précédée d'une indentation par rapport au nom de la
   1075 fonction sur la ligne qui précède.
   1076 Puis, lister les arguments de la fonction, en revenant à la ligne après
   1077 chacun d'eux et en les alignant les uns par rapport aux autres.
   1078 Ajouter la parenthèse fermante
   1079 .Ql \&)
   1080 et le point virgule
   1081 .Ql \&;
   1082 sur la ligne du dernier argument, sans espace supplémentaire :
   1083 .Bd -literal -offset Ds
   1084 extern LOCAL_SYM void
   1085 foo_bar
   1086   (struct foo* foo,
   1087    const int qux,
   1088    const float xyzzy);
   1089 .Ed
   1090 .Pp
   1091 Les différentes parties qui composent le profil de la fonction sont
   1092 ainsi identifiables par la seule mise en page de sa déclaration.
   1093 .Pp
   1094 Lors de sa définition, lister les arguments de la fonction sur la même
   1095 ligne que le nom de la fonction, sans ajouter d'espace entre le nom de
   1096 la fonction et sa parenthèse ouvrante :
   1097 .Bd -literal -offset Ds
   1098 void
   1099 foo_bar(struct foo* foo, const int qux, const float xyzzy)
   1100 {
   1101   ...
   1102 }
   1103 .Ed
   1104 .Pp
   1105 Si la liste des arguments dépasse la longueur maximale d'une ligne
   1106 .Pq section Sx LA LONGUEUR DES LIGNES
   1107 les lister comme pour une déclaration.
   1108 .Pp
   1109 Ordonner les arguments d'une fonction comme suit :
   1110 .Bl -enum -compact
   1111 .It
   1112 pour une fonction d'interface, la variable sur laquelle la fonction
   1113 opère ;
   1114 .It
   1115 les données d'entrées ;
   1116 .It
   1117 les données en sortie.
   1118 .El
   1119 .Pp
   1120 Ajouter l'instruction
   1121 .Ql const
   1122 aux variables qui n'ont pas vocation à être modifiées par la fonction.
   1123 Et ce quand bien même leur modification n'aurait aucune conséquence,
   1124 comme pour les variables de données simples, copiées à l'appel de la
   1125 fonction.
   1126 L'objet étant de souligner qu'elles sont des variables en entrée :
   1127 .Bd -literal -offset Ds
   1128 static void
   1129 foo
   1130   (struct foo* foo,
   1131    constr struct bar* bar,
   1132    const int longueur,
   1133    const int* liste,
   1134    int* resultat);
   1135 
   1136 static INLINE double
   1137 madd(const double a, const double b, const double c)
   1138 {
   1139   return a*b + c;
   1140 }
   1141 .Ed
   1142 .Pp
   1143 Ne passer en copie que les seuls paramètres en entrée de la fonction de
   1144 type primitif
   1145 .Pq Vt char , int , double , No énumération, ... .
   1146 Utiliser un pointeur constant dès lors que le paramètre d'entrée est
   1147 de type structuré, afin d'éviter le surcoût de sa copie à chaque appel de
   1148 fonction ; son occupation mémoire étant a priori plus important
   1149 qu'une donnée simple.
   1150 .Pp
   1151 Les paramètres d'une fonction peuvent ne pas être utilisés à l'intérieur
   1152 de celle-ci.
   1153 C'est notamment le cas si les paramètres ne sont utiles que pour
   1154 répondre à un profil de fonction spécifique ou dans un contexte de
   1155 compilation particulier, par exemple pour le débogage.
   1156 Lister ces paramètres en en-tête de la fonction, après
   1157 la définition des variables locales, en les préfixant d'une conversion
   1158 explicite vers un type vide :
   1159 .Bd -literal -offset Ds
   1160 static void
   1161 foo(int x, int y, int z)
   1162 {
   1163   int i = 0;
   1164   (void)y, (void)z; /* Paramètres inutilisés */
   1165 
   1166   i = bar(x);
   1167   if (i < 42) {
   1168     printf("Foobar\en");
   1169   }
   1170 }
   1171 .Ed
   1172 .Pp
   1173 Cette conversion explicite quels paramètres sont ignorés, en plus de
   1174 désactiver les avertissements de compilation quant à la définition de
   1175 paramètres non utilisés
   1176 .Pq option Fl Wunused-parameter No de Xr gcc 1 .
   1177 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1178 .Sh LES VARIABLES
   1179 Limiter le nombre de variables par bloc entre 5 et 10.
   1180 Un nombre de variables trop important peut être le signe d'un manque de
   1181 structure auquel un découpage en sous-fonction(s) pourrait remédier
   1182 .Pq section Sx LES FONCTIONS .
   1183 .Pp
   1184 Initialiser les variables dès leur définition avec sinon une valeur
   1185 valide, au moins une valeur par défaut.
   1186 L'objet étant d'éviter l'utilisation de variables non initialisées.
   1187 D'apparence peu critique pour les variables de type primitif, cette
   1188 initialisation l'est bien plus pour les variables structurées, dont la
   1189 liste des membres peut changer.
   1190 Si elle existe, utiliser la constante proposée avec la définition du
   1191 type structuré pour initialiser ses membres
   1192 .Pq voir section Sx LES STRUCTURES .
   1193 En son absence, n'initialiser que le premier membre de la variable ; le
   1194 language C assure alors que les autres membres seront initialisés à
   1195 zéro.
   1196 De même pour un tableau alloué sur la pile, initialiser son premier
   1197 élément suffit à garantir que le reste du tableau sera initialisé à
   1198 zero :
   1199 .Bd -literal -offset Ds
   1200 struct foo foo = FOO_DEFAULT;
   1201 struct bar bar = {0};
   1202 int qux[10] = {0};
   1203 int i = 0;
   1204 .Ed
   1205 .Pp
   1206 Au sein d'une même fonction, définir les variables au plus proche de
   1207 leur utilisation de sorte à ce que le contexte dans lequel elles sont
   1208 utilisées participe à les caractériser.
   1209 Par exemple, une variable
   1210 .Va i
   1211 utilisée dans un bloc comme variable temporaire, et comme indice de
   1212 boucle dans un autre, gagnera en expressivité et en robustesse à être
   1213 définie localement à chaque bloc ;
   1214 les deux variables étant alors, par construction, non seulement séparées
   1215 mais aussi sans effet de bord de l'une sur l'autre :
   1216 .Bd -literal -offset Ds
   1217 if(foo) {
   1218   const int i = bar();
   1219   if (i > max_i) max_val = i;
   1220   if (i < min_i) min_val = i;
   1221 } else {
   1222   int i = 0;
   1223   for(i = 0; i < N; ++i) qux(i);
   1224 }
   1225 .Ed
   1226 .Pp
   1227 Regrouper les définitions des variables dès lors qu'elles sont liées
   1228 sémantiquements.
   1229 Les trier ensuite par taille mémoire décroissante, et enfin par ordre
   1230 alphabétique :
   1231 .Bd -literal -offset Ds
   1232 /* Bibliothèque Foo */
   1233 struct foo_args foo_args = FOO_ARGS_DEFAULT;
   1234 struct foo* foo = NULL;
   1235 
   1236 /* Tableau à traiter */
   1237 double* liste = NULL;
   1238 int capacite = 0;
   1239 int longueur = 0;
   1240 .Ed
   1241 .Pp
   1242 Trier la définition des variables par taille mémoire tend à limiter le
   1243 nombre d'octets de remplissage que le compilateur C ajoute pour garantir
   1244 l'alignement mémoire de chaque variable eu égard à leur type.
   1245 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1246 .Sh LES CONSTANTES
   1247 Utiliser une énumération si les constantes à définir sont liées
   1248 sémantiquement, et une macro sinon :
   1249 .Bd -literal -offset Ds
   1250 #define ID_INVALIDE ((unsigned)-1)
   1251 
   1252 enum { X, Y, Z };
   1253 
   1254 enum attribut {
   1255   POSITION,
   1256   NORMALE,
   1257   TEXCOORD
   1258 };
   1259 .Ed
   1260 .Pp
   1261 Pour une énumération qui utilise des valeurs par défaut,
   1262 ajouter si besoin une dernière constante qui définit le nombre de
   1263 constantes valides ;
   1264 sa valeur sera ainsi automatiquement mise à jour à chaque changement de
   1265 l'énumération.
   1266 Une telle constante peut alors servir à définir la cardinalité d'un
   1267 tableau, comme valeur du dernier indice marquant la fin d'une itération,
   1268 ou encore comme valeur vis à vis de laquelle la validité d'une variable
   1269 du type énuméré peut être vérifiée :
   1270 .Bd -literal -offset Ds
   1271 enum molecule {
   1272   CH4,
   1273   CO,
   1274   CO2,
   1275   H2O,
   1276   N2O,
   1277   O3,
   1278 
   1279   NOMBRE_DE_MOLECULES
   1280 };
   1281 
   1282 /* Vérifier qu'une constante définie une molecule valide */
   1283 #define MOLECULE_EST_VALIDE(Mol) \e
   1284   ((unsigned)(Mol) < NOMBRE_DE_MOLECULES)
   1285 
   1286 static const char* NOM_DES_MOLECULES[NOMBRE_DE_MOLECULES] = {
   1287   "CH4", "CO", "CO2", "H2O", "N2O", "O3"
   1288 };
   1289 .Ed
   1290 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1291 .Sh LES STRUCTURES
   1292 Définir les structures en en-tête de fichier
   1293 .Pq section Sx LA STRUCTURE D'UN FICHIER SOURCE ,
   1294 à l'exeption des structures locales à une fonction.
   1295 .Pp
   1296 Lister les variables membres d'une structure suivant la même convention
   1297 que pour la définition des variables d'un bloc
   1298 .Pq section Sx LES VARIABLES Ns
   1299  :
   1300 les regrouper d'abord par sémantique, puis les trier par occupation
   1301 mémoire décroissante, et enfin par ordre alphabétique.
   1302 .Pp
   1303 Ne définir qu'une variable membre par ligne.
   1304 .Pp
   1305 Pour une structure dont aucune fonction ne permet d'en initialiser les
   1306 membres, définir une constante qui fixe leur valeur par défaut.
   1307 Suffixer cette constante par
   1308 .Ql DEFAULT
   1309 ou
   1310 .Ql NULL
   1311 fonction de si une variable structurée ainsi initialisée est une donnée
   1312 valide ou non.
   1313 Déclarer cette constante en tant que variable statique et l'initialiser par
   1314 une macro de même nom, différenciée de la variable constante par un
   1315 double tiret bas final
   1316 .Ql __ Ns
   1317  :
   1318 .Bd -literal -offset Ds
   1319 struct arg {
   1320   char* fichier; /* NULL <=> entrée standard */
   1321   int verbosite;
   1322 };
   1323 #define ARG_DEFAULT__ {NULL, 0}
   1324 static const struct arg ARG_DEFAULT = ARG_DEFAULT__;
   1325 
   1326 struct chaine {
   1327   char* mem;
   1328   int longueur;
   1329   int capacite;
   1330 };
   1331 #define CHAINE_NULL__ {NULL,0,0}
   1332 static const struct chaine CHAINE_NULL = CHAINE_NULL__;
   1333 .Ed
   1334 .Pp
   1335 N'utiliser la macro que lorsqu'il est impossible d'utiliser la variable
   1336 constante, en l'occurence pour initialiser, dès sa définition, les
   1337 membres d'une autre variable structurée :
   1338 .Bd -literal -offset Ds
   1339 struct qux {
   1340   struct chaine foo;
   1341   int bar;
   1342 };
   1343 #define QUX_DEFAULT__ {CHAINE_NULL__, 0}
   1344 static const struct qux QUX_DEFAULT = QUX_DEFAULT__;
   1345 .Ed
   1346 .Pp
   1347 Éviter d'utiliser une déclaration typedef des structures afin
   1348 d'autoriser leur déclaration anticipée.
   1349 Et l'utilisation de pointeur vers une donnée structurée sans avoir sa
   1350 définition.
   1351 Si un déclaration typedef est néanmoins souhaitée, nommer le type
   1352 structuré en suivant la convention de nommage des déclarations typedef
   1353 .Pq section Sx Les déclarations de types .
   1354 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1355 .Sh LES MACROS
   1356 Pour définir une séquence d'instructions,
   1357 préférer l'utilisation de fonctions aux macros.
   1358 Déclarer la fonction avec la directive
   1359 .Sy INLINE
   1360 si son coût d'appel est un enjeu
   1361 .Pq section Sx Les symboles internes à une unité de compilation .
   1362 .Pp
   1363 Regrouper la séquence d'instructions d'une macro dans un bloc terminé
   1364 par l'instruction
   1365 .Ql (void)0 .
   1366 Elle peut ainsi être utilisée comme unique expression d'une structure de
   1367 contrôle, et force l'ajout d'un point virgule
   1368 .Ql \&;
   1369 .Pq ou d'une virgule Ql \&,
   1370 après son utilisation, telle n'importe quelle autre instruction C.
   1371 .Pp
   1372 En C, il est plus courant d'encapsuler les instructions d'une macro
   1373 dans une structure de contrôle
   1374 .Ql do { ... } while (0)
   1375 plutôt que dans un bloc terminé par la converstion de l'entier zéro vers
   1376 un type vide
   1377 .Ql (void)0 .
   1378 Si les deux écritures répondent aux mêmes objectifs, cette dernière
   1379 convention évite les avertissements émis par certains compilateurs quant
   1380 à l'utilisation d'une expression conditionnelle constante dans
   1381 .Ql while (0) .
   1382 .Pp
   1383 Ouvrir le bloc sur la même ligne que le nom de la macro, en ajoutant un
   1384 espace avant l'acolade
   1385 .Ql { .
   1386 Indenter le contenu du bloc par rapport à la directive de définition de
   1387 la macro.
   1388 Justifer à droite les caractères anti-slash
   1389 .Ql \e
   1390 en fin de chaque ligne de sorte à faciliter la lecture de la séquence
   1391 d'instructions développée par la macro :
   1392 .Bd -literal -offset Ds
   1393 #define FOO(X, Y) {                                        \e
   1394   if ((X) == (Y)) printf("Bar \en");                        \e
   1395   (Y) += 2;                                                \e
   1396 } (void)0
   1397 .Ed
   1398 .Pp
   1399 À noter que dans l'exemple qui précède, les caractères anti-slash
   1400 .Ql \e
   1401 sont alignés en suivant des contraintes d'édition propres à ce manuel.
   1402 Dans un fichier source, positioner l'anti-slash en tant que dernier
   1403 caractère de lignes qui occupent la longueur maximale autorisée
   1404 .Pq section Sx LA LONGUEUR DES LIGNES .
   1405 .Pp
   1406 Pour une macro dont la portée est l'unité de compilation, ne pas changer
   1407 le déroulé des instructions de son contexte d'appel, par exemple en
   1408 intégrant une directive
   1409 .Ql return .
   1410 Son utilisation contredirait l'exécution séquentielle du code et ce
   1411 faisant nuirait à sa lisibilité.
   1412 Il n'est donc
   1413 .Em pas
   1414 recommandé de définir une macro comme suit :
   1415 .Bd -literal -offset Ds
   1416 #define FOO(X) {
   1417   if (bar(X))
   1418     return -1;
   1419 } (void)0
   1420 .Ed
   1421 .Pp
   1422 Ne pas présupposer l'existance de variables externes à la macro,
   1423 exeption faite des variables globales.
   1424 L'objet étant de ne pas lier son bon fonctionnement au contexte local
   1425 dans lequel elle est développée.
   1426 L'écriture qui suit est donc
   1427 .Em découragée Ns
   1428  :
   1429 .Bd -literal -offset Ds
   1430 #define BAR(X,Y) {
   1431   z = (X) + (Y);
   1432   if (xyzzy(z))
   1433     z += 1;
   1434 }
   1435 .Ed
   1436 .Pp
   1437 Contrairement aux macros définies à l'échelle d'une unité de
   1438 compilation, une macro locale peut non seulement changer le fil
   1439 d'exécution du contexte d'appel, mais aussi utiliser des variables
   1440 externes.
   1441 Et ce précisément en raison de son caractère local, qui lie étroitement
   1442 la macro à son seul contexte d'utilisation.
   1443 .Bd -literal -offset Ds
   1444 static int
   1445 foo(const int x)
   1446 {
   1447   char s[10] = {0};
   1448   int line = 0;
   1449   int err = 0;
   1450 
   1451   #define CALL(Func) {                                    \e
   1452     if((err=(Func)) != 0) {                               \e
   1453       line = __LINE__;                                    \e
   1454       goto error;                                         \e
   1455     }                                                     \e
   1456   } (void)0
   1457 
   1458   CALL(bar(x, s));
   1459   CALL(quux(s));
   1460 
   1461   #undef CALL
   1462 
   1463 exit:
   1464   return err;
   1465 error:
   1466   fprinf(stderr, "erreur %d ligne %d\en", err, line);
   1467   goto exit;
   1468 }
   1469 .Ed
   1470 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1471 .Sh LES ALLOCATIONS DYNAMIQUES
   1472 Préférer l'interface d'allocation proposée par la
   1473 bibliothèque
   1474 .Ql RSys
   1475 via son fichier d'en-tête
   1476 .In rsys/mem_allocator.h .
   1477 Elle enrichit la gestion de la mémoire dynamique proposée par la
   1478 bibliothèque C standard, notamment en enregistrant la quantité de
   1479 mémoire allouée.
   1480 .Pp
   1481 Utiliser dès lors les fonctions
   1482 .Fn mem_alloc ,
   1483 .Fn mem_calloc
   1484 et
   1485 .Fn mem_realloc
   1486 pour allouer dynamiquement de la mémoire.
   1487 Leur profil est celui des fonctions équivalentes proposées par la
   1488 bibliothèque C, à savoir ces mêmes fonctions mais sans le prefixe
   1489 .Ql mem_
   1490 .Po
   1491 voir
   1492 .Xr alloc 3 ,
   1493 .Xr calloc 3 ,
   1494 et
   1495 .Xr realloc 3
   1496 .Pc .
   1497 .Pp
   1498 Privilégier la fonction
   1499 .Fn mem_calloc
   1500 à
   1501 .Fn mem_alloc
   1502 de sorte à initialiser la mémoire allouée à zéro, et d'éviter ainsi
   1503 d'utiliser des données non initialisées.
   1504 .Pp
   1505 Ne pas convertir le pointeur retourné par les fonctions d'allocation.
   1506 La conversion d'un pointeur vide vers n'importe quel autre type de
   1507 pointeur est déjà assuré par le langage C.
   1508 .Pp
   1509 Définir la taille du bloc mémoire à allouer via le type pointé par la
   1510 variable destination :
   1511 .Bd -literal -offset Ds
   1512 p = mem_calloc(42, sizeof(*p));
   1513 .Ed
   1514 .Pp
   1515 L'alternative qui consiste à épeller le type pointé en argument de
   1516 .Ql sizeof
   1517 non seulement nuit à la lisibilité des sources, mais laisse en plus
   1518 l'opportunité d'introduire un bogue dès lors que le type de pointeur
   1519 est mis à jour mais pas le nom du type renseigné à
   1520 .Ql sizeof .
   1521 .Pp
   1522 Utiliser la fonction
   1523 .Fn mem_alloc_aligned
   1524 pour allouer un bloc mémoire dont l'adresse doit être alignée sur un
   1525 nombre d'octets spécifique.
   1526 Utiliser la fonction
   1527 .Xr memset 3 ,
   1528 de la bibliothèque C standard, pour forcer la mise à zéro du bloc ainsi
   1529 alloué sinon rempli d'octets
   1530 aléatoires :
   1531 .Bd -literal -offset Ds
   1532 foo = mem_alloc_aligned(sizeof(*foo), 128/* Alignement */);
   1533 memset(foo, 0, sizeof(*foo));
   1534 .Ed
   1535 .Pp
   1536 Vérifier chaque allocation en testant que l'adresse retournée n'est pas
   1537 .Ql NULL .
   1538 Traiter ce cas comme une erreur et non un bogue
   1539 .Pq section Sx CENTRALISER LA SORTIE D'UNE FONCTION Ns
   1540  :
   1541 .Bd -literal -offset Ds
   1542   foo = mem_calloc(1, sizeof(*foo);
   1543   if (!foo) {
   1544     res = RES_MEM_ERR;
   1545     goto error;
   1546   }
   1547 .Ed
   1548 .Pp
   1549 Libérer la mémoire allouée via
   1550 .Ql RSys
   1551 avec la fonction
   1552 .Fn  mem_rm
   1553 dont le profil est le même que celui de la fonction
   1554 .Xr free 3 Ns
   1555  :
   1556 .Bd -literal -offset Ds
   1557 mem_rm(foo);
   1558 .Ed
   1559 .Pp
   1560 Détecter la présence de fuites mémoires via la fonction
   1561 .Fn mem_allocated_size
   1562 qui retourne la quantité de mémoire qui reste allouée par la
   1563 bibliothèque :
   1564 .Bd -literal -offset Ds
   1565 int
   1566 main(void)
   1567 {
   1568   size_t sz = 0;
   1569   int err = 0;
   1570 
   1571   ...
   1572 
   1573   if ((sz = mem_alloc_aligned()) != 0) {
   1574     fprintf(stderr, "Fuites mémoires : %lu octets\en", sz);
   1575     if (err == 0) err = 1;
   1576   }
   1577   return err;
   1578 }
   1579 .Ed
   1580 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1581 .Ss Les allocateurs mémoire
   1582 Dans son fichier d'en-tête
   1583 .In rsys/mem_allocator.h ,
   1584 la bibliothèque
   1585 .Ql RSys
   1586 définit en plus une interface d'allocateur mémoire.
   1587 Au contraire de son interface d'allocation qui enregistre la mémoire
   1588 alloué globalement par la bibliothèque,
   1589 chaque allocateur enregistre ses seules allocations.
   1590 .Pp
   1591 Plusieurs types d'allocateurs sont proposés par la bibliothèque
   1592 .Ql RSys ,
   1593 chacun mettant en oeuvre une politique d'allocation qui lui est propre.
   1594 Si bien qu'en fonction du contexte, un type d'allocateur particulier
   1595 peut s'avérer plus approprié, par exemple pour réduire les coûts
   1596 d'allocations/désallocations.
   1597 Décrire les différents types d'allocateurs définis dans la bibliothèque
   1598 .Ql RSys
   1599 sort du cadre de cette documentation.
   1600 Le lecteur est invité à se référer à son fichier d'en-tête
   1601 .In rsys/mem_allocator.h
   1602 pour plus d'informations.
   1603 .Pp
   1604 Les convention listées précédemment quant aux allocation dynamiques
   1605 s'appliquent à l'identique à l'utilisation des allocateurs.
   1606 .Pp
   1607 Utiliser un allocateur consiste à appeler des macros, dont le nom est
   1608 une version en majuscule des fonctions de l'interface d'allocation.
   1609 Avec en plus en premier argument l'addresse de l'allocateur concerné :
   1610 .Bd -literal -offset Ds
   1611 foo = MEM_CALLOC(&mem_default_allocator, 1, sizeof(*foo));
   1612 
   1613 \&...
   1614 
   1615 MEM_RM(&mem_default_allocator, foo);
   1616 
   1617 if (MEM_ALLOCATED_SIZE(&mem_default_allocator)) {
   1618   fprintf(stderr, "Fuites mémoires\en");
   1619 }
   1620 .Ed
   1621 .Pp
   1622 avec
   1623 .Va mem_default_allocator
   1624 l'allocateur par défaut définit par la bibliothèque
   1625 .Ql RSys .
   1626 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1627 .Sh CENTRALISER LA SORTIE D'UNE FONCTION
   1628 Utiliser la directive
   1629 .Ql goto
   1630 pour centraliser les traitements à effectuer en sortie de fonction, tels
   1631 les affectations de variables de sorties, les libérations de variables
   1632 locales temporaires, ou le renvoie d'une valeur en retour de la fonction.
   1633 Regrouper ces traitements en fin de fonction sous le label
   1634 .Ql exit
   1635 dont la dernière instruction est la valeur retournée par la fonction.
   1636 .Pp
   1637 De même, centraliser la gestion des erreurs détectées pendant
   1638 l'exécutation de la fonction sous un label
   1639 .Ql error ,
   1640 qui vise à revenir à l'état du programme avant l'appel de la fonction,
   1641 et à préparer son retour compte tenu de l'erreur.
   1642 Ses traitements recouvrent notamment la libération de
   1643 l'espace mémorie alloué à destination de l'appelant, la restauration des
   1644 données en mise à jour modifiées par la fonction avant la détection de
   1645 l'erreur, ou la définition de valeurs à destination des variables en
   1646 sortie en conséquence de l'erreur détectée.
   1647 .Pp
   1648 Placer le label
   1649 .Ql error
   1650 après le label
   1651 .Ql exit .
   1652 Terminer la gestion des erreurs par la directive
   1653 .Ql goto exit ,
   1654 de sorte à effectuer les traitements en sortie,
   1655 .Em indépendants
   1656 de la présence ou non d'une erreur d'exécution, et donc à appliquer en
   1657 toute circonstance.
   1658 En structurant les labels de la sorte, les traitements en sortie
   1659 .Pq label Ql exit
   1660 sont ainsi exécutés soit automatiquement au fil du bon déroulé de la
   1661 fonction, sans que l'auteur(e) n'est nécessairement à le préciser.
   1662 Soit après la détection d'une erreur dont la gestion explicite via la
   1663 directive
   1664 .Ql goto error
   1665 précède la sortie de la fonction et ses traitements associés ; auxquels
   1666 renvoit finalement la gestion des erreurs centralisée sous le label
   1667 .Ql error .
   1668 .Bd -literal -offset Ds
   1669 static res_T
   1670 foo(const int bar, int** out_list)
   1671 {
   1672   int* list = NULL;
   1673   res_T res = RES_OK;
   1674 
   1675   if (out == NULL) {
   1676     res = RES_BAD_ARG;
   1677     goto error;
   1678   }
   1679 
   1680   if ((list = mem_calloc(42, sizeof(*list)) == NULL) {
   1681     res = RES_MEM_ERR;
   1682     goto error;
   1683   }
   1684 
   1685   if ((res = quux(bar, list)) != RES_OK) goto error;
   1686 
   1687 exit:
   1688   if (out_list != NULL) *out_list = list;
   1689   return res;
   1690 error:
   1691   if (list) { mem_rm(list); list = NULL; }
   1692   goto exit;
   1693 }
   1694 .Ed
   1695 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1696 .Sh LES PROGRAMMES EN LIGNE DE COMMANDE
   1697 Privilégier une interface en ligne de commande pour les programmes
   1698 directement exécutables par l'utilisateur.
   1699 À la fois simple et légère, elle s'intègre parfaitement aux shells, que
   1700 ce soit en session interactive ou via des scripts.
   1701 Plus qu'une interface utilisateur elle est ainsi une interface vers le
   1702 système UNIX dont le programme peut alors directement tirer partie, que
   1703 ce soit en terme de gestion d'entrées/sorties ou de communication
   1704 inter-processus avec d'autres utilitaires, par exemple via des tubes
   1705 shell.
   1706 .Pp
   1707 Analyser les arguments du programme en utilisant la fonction
   1708 .Xr getopt 3
   1709 définie par le standard POSIX.1-2001 dans l'en-tête
   1710 .In unistd.h
   1711 de la bibliohtèque C.
   1712 Cette fonction assure la consistante de l'analyse des arguments et
   1713 participe au respect des conventions énoncées par le standard POSIX pour
   1714 les utilitaires en ligne de commandes.
   1715 .Pp
   1716 Proposer l'option
   1717 .Fl h
   1718 qui affiche le seul synopsis de la commande en guise de résumé de ses
   1719 attendus et options.
   1720 Réserver la description du programme et de ses options à sa page de
   1721 manuel.
   1722 Afficher ce même synopsis en cas d'erreur lors de l'analyse des
   1723 arguments de sorte à renvoyer l'utilisateur vers la syntaxe de la
   1724 commande.
   1725 .Bd -literal -offset Ds
   1726 static void
   1727 usage(FILE* stream)
   1728 {
   1729   fprintf(stream, "usage: foo [-hv] [-b bar]\en");
   1730 }
   1731 
   1732 int
   1733 main(int argc, char** argv)
   1734 {
   1735   FILE* bar = NULL;
   1736   int err = 0;
   1737   int opt = 0;
   1738   int verbosity = 0;
   1739 
   1740   while ((opt = getopt(argc, argv, "b:hv")) != -1) {
   1741     switch (opt) {
   1742       case 'a':
   1743         if((bar = fopen(optarg, "r")) == NULL) err = 1;
   1744         break;
   1745       case 'h': usage(stdout); goto exit;
   1746       case 'v': verbosity += (verbosity < 3); break;
   1747       default: err = 1; break;
   1748     }
   1749     if (err) { usage(stderr); goto error; }
   1750   }
   1751   if (bar == NULL) bar = stdin;
   1752 
   1753   if ((err = foo(bar, verbosity)) != 0) goto error;
   1754 
   1755 exit:
   1756   if(bar && bar != stdin) fclose(bar);
   1757   return err;
   1758 error:
   1759   goto exit;
   1760 }
   1761 .Ed
   1762 .Pp
   1763 Dès que possible, donner la possibilité de lire les données d'entrée du
   1764 programme directement sur l'entrée standard.
   1765 Il pourra ainsi être chaîné avec un autre processus en charge, par
   1766 exemple, de pré-traiter ses données d'entrée.
   1767 De même, écrire les données en sortie du programme sur la sortie
   1768 standard pour qu'un autre utilitaire puisse en post-traiter le
   1769 résultat.
   1770 Si plusieurs fichiers d'entrée/de sortie sont lus/écrits par le
   1771 programme, définir les données le plus à même d'être pré/post-traitées
   1772 pour choisir lesquelles seront lues/écriture sur l'entrée/la sortie
   1773 standard.
   1774 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1775 .Sh FICHIERS
   1776 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
   1777 .Sh VOIR AUSSI
   1778 .Xr gcc 1 ,
   1779 .Xr getopt 3 ,
   1780 .Xr feature_test_macros 7
   1781 .Pp
   1782 .Rs
   1783 .%A IEEE
   1784 .%A The Open Group
   1785 .%R Base Definitions, POSIX.1-2001
   1786 .%T Section 12, Utility Conventions
   1787 .Re
   1788 .Pp
   1789 .Rs
   1790 .%A La Fondation pour le logiciel libre
   1791 .%T Comment utiliser les licences GNU pour vos logiciels
   1792 .%U https://www.gnu.org/licenses/gpl-howto.fr.html
   1793 .Re