star-style

Writing conventions for co-authors
git clone git://git.meso-star.com/star-style.git
Log | Files | Refs | README | LICENSE

star-c.7.in (56318B)


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