star-style

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

star-c.7 (25523B)


      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 June 26, 2026
     19 .Dt STAR-C 7
     20 .Os
     21 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
     22 .Sh NOM
     23 .Nm star-c
     24 .Nd guide d'écriture de code en C
     25 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
     26 .Sh DESCRIPTION
     27 Ce document décrit les conventions d'écriture des programmes C
     28 distribués par |Méso|Star>.
     29 Ces recommandations sont données à titre indicatif, et reste
     30 subordonnées aux pratiques effectivement retenues dans chaque
     31 projet ; le plus important étant d'en conserver la cohérence.
     32 Si bien que s'il appartient aux co-auteurs d'un projet de prendre
     33 certaines libertés quant à ce guide de style, toute participation à son
     34 développement devra alors s'efforcer de respecter le style d'écriture du
     35 projet, avant les préférences listées ici.
     36 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
     37 .Sh LE CONTENU D'UN PROJET
     38 En suivant le philosophie UNIX, assurer un jeu de
     39 fonctionnalités par programme aussi ramassé que possible de
     40 sorte à ce que sa mise en oeuvre et son interface restent
     41 simples et ciselées.
     42 L'objet étant d'assurer sa robustesse, son efficacité et sa
     43 modularité qui dépendent d'abord de sa
     44 .Em relation
     45 à un écosystème logiciel qui le dépasse, bien avant son catalogue de
     46 fonctionnalités ou ses prouesses de mise en oeuvre.
     47 .Pp
     48 Le périmètre étroit de chaque programme se retrouve dès lors dans la
     49 structure du projet auquel il appartient, dont le contenu est alors
     50 simple et peu hiérarchisé car comptant en définitive peu de fichiers.
     51 .Pp
     52 La structure type du répertoire d'un projet est :
     53 .Bd -literal -offset Ds
     54 README.md
     55 COPYING
     56 config.mk
     57 Makefile
     58 src/foo.h
     59 src/foo.c
     60 src/foo_bar.c
     61 doc/foo_bar.1
     62 doc/foo.3
     63 .Ed
     64 .Pp
     65 Avec :
     66 .Bl -dash -compact
     67 .It
     68 .Pa README.md
     69 le fichier qui donne le premier niveau d'informations sur le projet ;
     70 .It
     71 .Pa COPYING
     72 la license du projet qui liste ses conditions légales d'utilisation ;
     73 .It
     74 .Pa config.mk
     75 et
     76 .Pa Makefile
     77 les fichiers du système de génération automatique ;
     78 .It
     79 .Pa src/
     80 le répertoire qui contient les codes source du projet ;
     81 .It
     82 .Pa doc/
     83 le répertoire qui stocke sa documentation.
     84 .El
     85 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
     86 .Sh LE LANGAGE C
     87 Utiliser le langage
     88 .Em C89
     89 .Pq ANSI X3.159-1989
     90 aussi appelé C90
     91 .Pq ISO/IEC 9899:1990 ,
     92 les deux étant équivalent.
     93 .Pp
     94 Cette norme est plus épurée que celle qui lui succède à savoir le C99
     95 .Pq ISO SO/IEC 9899:1999 ,
     96 ce qui en fait un dialecte C à la fois plus simple, plus portable et
     97 plus consistant.
     98 Par exemple en ne proposant qu'une seule façon d'écrire les commentaires,
     99 et en interdisant de mélanger du code avec la définition de variables.
    100 .\""""""""""""""""""""""""""""""""""
    101 .Ss Le standard POSIX
    102 Ajouter le support du standard POSIX pour les seuls fichiers qui en ont
    103 besoin, pour notamment pouvoir utiliser des fonctions de la bibliothèque
    104 C standard sinon indisponibles via la seule norme du langage retenue.
    105 .Pp
    106 Pour ce faire, définir la macro
    107 .Sy _POSIX_C_SOURCE
    108 tout en haut du fichier C concerné, avant la moindre directive
    109 d'inclusion.
    110 Par exemple, pour utiliser le standard POSIX.1-2001 :
    111 .Bd -literal -offset Ds
    112 #define _POSIX_C_SOURCE 200112L
    113 .Ed
    114 .Pp
    115 Sous GNU/Linux, se référer à
    116 .Xr feature_test_macros 7
    117 pour une description exhaustive des macros utilisées pour activer le jeu
    118 de fonctionnalités d'un standard donné.
    119 .Pp
    120 L'utilisation d'un C enrichi du standard POSIX n'est ainsi utilisé que
    121 sur les seuls fichiers qui en explicite le besoin ; le C89 restant le
    122 langage utilisé partout ailleurs.
    123 Dans un même souci de portabilité, retenir la première version du
    124 standard POSIX à partir de laquelle la fonctionnalité recherchée est
    125 apparue.
    126 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    127 .Sh LA STRUCTURE D'UN FICHIER SOURCE
    128 Suivre une seule et même structure pour tous les fichiers
    129 sources, qu'ils soient des fichiers d'en-tête
    130 .Pq fichiers Ql *.h
    131 ou des unités de compilation
    132 .Pq fichiers Ql *.c .
    133 Un seul schéma de lecture participant à la clarté du code source.
    134 .Pp
    135 Ci-après sont listées les différentes parties d'un fichier source :
    136 .Bl -enum
    137 .\""""""""""""""""""""""""""""""""""
    138 .It
    139 Un commentaire avec l'avis de copyright et les avis de licence du
    140 programme
    141 .Pq section Sx L'AVIS DE COPYRIGHT ET LES AVIS DE LICENCE Ns
    142  ;
    143 .\""""""""""""""""""""""""""""""""""
    144 .It
    145 La définition d'une macro qui ajoute au langage C du fichier le support
    146 d'un standard POSIX
    147 .Pq section Sx LE LANGAGE C Ns
    148  ;
    149 .\""""""""""""""""""""""""""""""""""
    150 .It
    151 Pour un fichier d'en-tête, l'ouverture d'un garde-fou évitant sa double
    152 inclusion.
    153 Il est fermé en toute fin du fichier
    154 .Pq partie 10 Ns
    155  :
    156 .Bd -literal -offset Ds
    157 #ifndef FOO_H
    158 #define FOO_H
    159 .Ed
    160 .Pp
    161 Le nom de la macro testée puis définie est celui du fichier d'en-tête,
    162 suffixé par
    163 .Ql _H
    164 en référence à l'extension
    165 .Ql .h
    166 du fichier.
    167 Dans l'exemple qui précède, le garde-fou concerne donc le fichier
    168 .In foo.h .
    169 La convention d'écriture est sinon celle utilisée pour n'importe quelle
    170 macro
    171 .Pq section Sx LES MACROS .
    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é externe au programme */
    187 struct logger;
    188 
    189 /* Type structuré défini ailleurs dans le programme */
    190 struct foo;
    191 .Ed
    192 .\""""""""""""""""""""""""""""""""""
    193 .It
    194 La définition des constantes symboliques
    195 de type
    196 .Vt enum
    197 .Pq section Sx LES CONSTANTES SYMBOLIQUES Ns
    198  ;
    199 .\""""""""""""""""""""""""""""""""""
    200 .It
    201 La définition des types structurés et de leur(s) constante(s)
    202 .Pq section Sx LES STRUCTURES Ns
    203  ;
    204 .\""""""""""""""""""""""""""""""""""
    205 .It
    206 La déclaration et définition des fonctions
    207 .Pq section Sx LES FONCTIONS .
    208 Dans l'ordre qui suit :
    209 .Pp
    210 .Bl -tag -compact -width a.
    211 .It a.
    212 La déclaration des fonctions ;
    213 .It b.
    214 La définition des fonctions statiques ;
    215 .It c.
    216 Pour les unités de compilations, la définition des fonctions.
    217 .El
    218 .\""""""""""""""""""""""""""""""""""
    219 .It
    220 Pour les fichiers d'en-tête, la fin du garde-fou ouvert en 3 pour éviter
    221 la double inclusion du contenu du fichier.
    222 .El
    223 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    224 .Sh LA LONGUEUR DES LIGNES
    225 La longueur maximale recommandée pour une ligne est de
    226 .Em 80
    227 caractères.
    228 .Pp
    229 Ce nombre, standardisé par les cartes perforées et les terminaux des
    230 années 1970, vise aussi à faciliter la lecture du code source en
    231 s'insipirant des conventions d'édition.
    232 Pour un texte imprimé avec une taille de police entre 9 à 12 points et
    233 un inter-ligne d'un caractère, un confort de lecture est assuré dès
    234 lors que chaque ligne compte entre 60 et 75 caractères.
    235 Une proximité avec les 80 caractères retenus, que l'indentation
    236 des sources vient encore renforcer.
    237 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    238 .Sh L'AVIS DE COPYRIGHT ET LES AVIS DE LICENCE
    239 Utiliser la licence libre GPLv3+ qui, en tant que licence copyleft,
    240 défend la copie, l'étude et la modification libres du programme ainsi
    241 licencié, et de ses évolutions.
    242 .Pp
    243 Ajouter une copie de la licence à la racine du projet, dans un fichier
    244 texte nommé
    245 .Pa COPYING
    246 .Pq voir Lk https://www.gnu.org/licenses/gpl-3.0.txt .
    247 .Pp
    248 Lister en commentaire l'avis de copyright et la déclaration
    249 d'autorisation de copie en en-tête de
    250 .Em chaque
    251 fichier source.
    252 .Pp
    253 Chaque copyright débute par le mot
    254 .Ql Copyright ,
    255 en anglais, suivi des 3 caractères
    256 .Ql (C) ,
    257 traduction ASCII du caractère © qui, quant à lui, peut ne pas être
    258 supporté par les jeu de caractères utilisé.
    259 Lister ensuite les années pour lesquelles une version du programme a été
    260 publiée, avant le nom de l'auteur(e) ayant participé(e) à
    261 sa réalisation.
    262 Conclure chaque avis par l'adresse de contact de l'auteur(e), donnée
    263 entre parenthèses.
    264 .Pp
    265 Sauter une ligne après l'avis de copyright et ajouter la déclaration
    266 autorisant la copie telle que donnée par la Foundation pour le logiciel
    267 libre.
    268 .Pp
    269 L'en-tête type d'un fichier source du programme
    270 .Ql Foo
    271 est :
    272 .Bd -literal -offset Ds
    273 /* Copyright (C) 2016-2018, 2020, 2022, 2026
    274  *   Jeanne Lambda (jeanne.lambda@courriel.fr)
    275  * Copyright (C) 2017, 2019 Jean Untel (juntel@courriel.fr)
    276  * Copyright (C) 2024 |Méso|Star> (contact@meso-star.com)
    277  *
    278  * This file is part of Foo.
    279  *
    280  * Foo is free software: you can redistribute it and/or
    281  * modify it under the terms of the GNU General Public License
    282  * as published by the Free Software Foundation, either
    283  * version 3 of the License, or (at your option) any later
    284  * version.
    285  *
    286  * Foo is distributed in the hope that it will be useful,
    287  * but WITHOUT ANY WARRANTY; without even the implied warranty
    288  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
    289  * the GNU General Public License for more details.
    290  *
    291  * You should have received a copy of the GNU General Public
    292  * License along with Foo. If not, see
    293  * <https://www.gnu.org/licenses/>. */
    294 .Ed
    295 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    296 .Sh L'INDENTATION
    297 Indenter le texte par 2 espaces.
    298 La mise en page du texte, taille de ligne comprise, est ce faisant
    299 indépendante de la taille d'une tabulation.
    300 .Pp
    301 Les auteurs sont encouragés à configurer leur éditeur pour
    302 qu'il développe chaque caractère tabulation en 2 espaces
    303 .Pq section Sx FICHIERS .
    304 Et ainsi continuer à utiliser la touche tabulation pour l'indentation.
    305 .Pp
    306 Limiter l'indentation à 2 caractères, contre 8 pour le standard de facto
    307 des tabulations, laisse plus d'espace aux différents niveaux
    308 d'indentation, dès lors moins contraints par la limite du nombre de
    309 caractères par ligne
    310 .Pq section Sx LA LONGUEUR DES LIGNES .
    311 Néanmoins, un niveau d'indentation supérieur à 3 est aussi le signe d'un
    312 déficit de structure dans l'écriture du programme.
    313 Les 2 espaces retenus pour indenter le code n'est donc pas une
    314 incitation à aller au delà de 3 niveaux d'indentation sous prétexte de
    315 disposer de plus d'espace par niveau.
    316 .Pp
    317 Indenter le contenu de chaque bloc
    318 .Pq section Sx LES BLOCS .
    319 Pour la directive
    320 .Ql switch ,
    321 indenter chaque
    322 .Ql case
    323 ainsi que leur contenu :
    324 .Bd -literal -offset Ds
    325 switch (opt) {
    326   case 'e':
    327     errno = 0;
    328     epsilon = strtod(optarg, NULL);
    329     if (errno != 0) err = 1;
    330     break;
    331   case 'h':
    332     printf("usage: foo [-hov]\en");
    333     break;
    334   case 'o':
    335     output = optarg;
    336     break;
    337   case 'v':
    338     verbose += (verbose < 3);
    339     break;
    340   default:
    341     err = 1;
    342     break;
    343 }
    344 .Ed
    345 .Pp
    346 Motiver l'utilisation de plusieurs instructions par ligne par
    347 l'expressivité du code en résultant, qu'une écriture resserrée viendrait
    348 renforcer :
    349 .Bd -literal -offset Ds
    350 if (x == NULL || y == NULL) { err = 1; goto error; }
    351 x[0] = 1.0; x[1] = 0.0;
    352 y[0] = 0.0; y[1] = 1.0;
    353 .Ed
    354 .Pp
    355 Ne sauter au plus qu'une ligne.
    356 Ne pas laisser d'espace en fin de ligne et supprimer les lignes vides
    357 en fin de fichier.
    358 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    359 .Sh LES COMMENTAIRES
    360 Utiliser des commentaires dès lors que la seule expressivité serrée du
    361 code ne permet pas d'exprimer l'entièreté du discours que les sources
    362 doivent rendre compte, ou la logique qu'il met effectivement en oeuvre.
    363 .Pp
    364 Si un commentaire occupe plusieurs lignes, ajouter un caractère
    365 .Ql *
    366 en début de ligne, aligné avec le caractère
    367 .Ql *
    368 de la ligne qui précède :
    369 .Bd -literal -offset Ds
    370 /* Valeurs de hachage initiales, à savoir les 32 premiers bits
    371  * de la partie fractionnaire des racines carrées des 4 premiers
    372  * nombres premiers (2, 3, 5 et 7) */
    373 state[0] = 0x6a09e667;
    374 state[1] = 0xbb67ae85;
    375 state[2] = 0x3c6ef372;
    376 state[3] = 0xa54ff53a;
    377 .Ed
    378 .Pp
    379 Les commentaires servent aussi à structurer la lecture du code source.
    380 Que ce soit à l'échelle des instructions, par un commentaire
    381 .Dq chapeau
    382 qui résume la séquence de code qui suit :
    383 .Bd -literal -offset Ds
    384 /* Enregistrer le résultat */
    385 ((uint32_t*)hash)[0] = big_endian_32(state[0]);
    386 ((uint32_t*)hash)[1] = big_endian_32(state[1]);
    387 ((uint32_t*)hash)[2] = big_endian_32(state[2]);
    388 ((uint32_t*)hash)[3] = big_endian_32(state[3]);
    389 .Ed
    390 .Pp
    391 ou à l'échelle du fichier, où les commentaires servent alors de
    392 séparateur entre ses différentes sections
    393 .Pq voir Sx LA STRUCTURE D'UN FICHIER SOURCE .
    394 Dans ce cas, encadrer le commentaire par deux ligne de caractères
    395 .Ql *
    396 qui débute ou se termine par le caractère
    397 .Ql /
    398 si, respectivement, la ligne précède ou suit l'intitulé de la section :
    399 .Bd -literal -offset Ds
    400 /***********************************************************
    401  * Définition des fonctions utilitaires
    402  **********************************************************/
    403 static void
    404 process_chunk(uint32_t state[4], const char chunk[64])
    405 {
    406   ...
    407 }
    408 .Ed
    409 .Pp
    410 À noter que dans l'exemple qui précède, la taille des lignes
    411 d'encadrement est limitée par des contraintes d'édition de la présente
    412 page de manuel.
    413 Dans un fichier source, étendre ces lignes pour qu'elles occupent la
    414 longueur maximale recommandée pour une ligne, à savoir 80 caractères.
    415 .Pp
    416 Pour expliciter le contexte général d'un fichier, en terme d'utilisation
    417 ou d'architecture logicielle, insérer un commentaire en en-tête du
    418 fichier en laissant les caractères d'ouverture ou de fermeture de
    419 commentaires sur une ligne séparée :
    420 .Bd -literal -offset Ds
    421 /*
    422  * Interface de programmation des tableaux extensibles.
    423  * Cette structure de données peut être utilisée avec des
    424  * types de données qui ne nécessitent pas de processus
    425  * d'initialisation ou de libération et qui peuvent être
    426  * copiés bit à bit
    427  */
    428 .Ed
    429 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    430 .Sh LES FICHIERS D'EN-TÊTE
    431 Inclure les fichiers d'en-tête dans l'ordre qui suit :
    432 .Bl -enum -compact
    433 .It
    434 les en-têtes locaux au programme ;
    435 .It
    436 les en-têtes des dépendances ;
    437 .It
    438 les en-têtes systèmes et de la bibliothèque C standard.
    439 .El
    440 .Pp
    441 Les fichiers d'en-tête sont ainsi inclus dans l'ordre décroissant de
    442 leur niveau d'abstraction.
    443 Cet ordre participe à garantir que chaque fichier d'en-tête inclus les
    444 en-têtes dont il a lui même besoin, indépendamment des directives
    445 d'inclusion qui précèdent sa propre inclusion.
    446 Si ce n'est pas le cas, la compilation pourra échouer, symptôme qu'un
    447 des fichiers d'en-tête n'est pas auto-consistant.
    448 .Pp
    449 Dans chaque groupe, trier les directives d'inclusion par ordre
    450 alphabétique des fichiers d'en-tête.
    451 Si besoin, ajouter un commentaire court, sur la même ligne que la
    452 directive d'inclusion, qui explicite la raison pour laquelle la fichier
    453 est inclus.
    454 .Bd -literal -offset Ds
    455 #include "bar.h"
    456 #include "foo.h"
    457 #include "qux.h"
    458 
    459 #include <baz.h>
    460 
    461 #include <float.h> /* FLT_MAX */
    462 #include <stdio.h>
    463 .Ed
    464 .Pp
    465 S'efforcer de n'inclure que les seuls fichiers d'en-tête
    466 réellement nécessaires au fichier ;
    467 par exemple par une déclaration anticipée des types structurés à
    468 la place d'inclure des en-têtes dans le seul but de déclarer lesdits
    469 types.
    470 Un enjeu a considérer avec d'autant plus d'attention que le fichier
    471 concerné par les inclusions est lui même un fichier d'en-tête, par
    472 conséquent amené à être lui même inclus.
    473 L'objet étant de limiter autant que possible le nombre de fichiers
    474 inclus par unité de compilation, pour limiter les accès disque et ainsi
    475 réduire les temps de compilation.
    476 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    477 .Sh LA VISIBILITÉ DES SYMBOLES
    478 Par défaut, n'exposer aucun symbole
    479 .Po
    480 option
    481 .Fl fvisibility=hidden
    482 du compilateur
    483 .Xr gcc 1
    484 .Pc ,
    485 à l'exception de ceux de l'interface de programmation d'une
    486 bibliothèque.
    487 .\""""""""""""""""""""""""""""""""""
    488 .Ss Les symboles d'interface
    489 Privilégier l'écriture d'un seul fichier d'en-tête pour exposer
    490 l'interface de programmation d'une bibliothèque.
    491 Y définir une macro qui exporte les symboles qu'elle déclare dès lors
    492 que ce fichier d'en-tête est inclus par une unité de compilation de la
    493 bibliothèque.
    494 Et qui se contente d'importer ces mêmes symboles si ce même fichier est
    495 inclus par un programme tiers :
    496 .Bd -literal -offset Ds
    497 #include <rsys/rsys.h>
    498 
    499 #if defined(FOO_SHARED_BUILD)
    500   #define FOO_API extern EXPORT_SYM
    501 else
    502   #define FOO_API extern IMPORT_SYM
    503 #endif
    504 .Ed
    505 .Pp
    506 Avec :
    507 .Bl -dash -compact
    508 .It
    509 .Sy FOO_SHARED_BUILD
    510 une macro définie uniquement à la compilation de la bibliothèque
    511 .Po
    512 option
    513 .Fl DFOO_SHARED_BUILD
    514 du compilateur C
    515 .Pc Ns
    516  ;
    517 .It
    518 .Sy EXPORT_SYM
    519 et
    520 .Sy IMPORT_SYM
    521 des directives définies dans la bibliothèque RSys.
    522 Elles enrichissent le langage C d'une gestion explicite de la visibilité
    523 des symboles.
    524 .El
    525 Utiliser cette macro à la déclaration des variables et constantes
    526 d'interfaces :
    527 .Bd -literal -offset Ds
    528 /* Variables globales de l'interface de programmation */
    529 FOO_API const struct foo foo_plugh;
    530 FOO_API const struct foo foo_xyzzy;
    531 .Ed
    532 .Pp
    533 Déclarer en plus le prototype des fonctions d'interface entre les
    534 directives
    535 .Sy BEGIN_DECLS
    536 et
    537 .Sy END_DECLS ,
    538 elles aussi définies dans la bibliothèque RSys
    539 .Pq en-tête In rsys/rsys.h .
    540 Ainsi, le fichier d'en-tête peut être inclus par un programe C++ :
    541 .Bd -literal -offset Ds
    542 BEGIN_DECLS
    543 
    544 FOO_API void
    545 foo_bar
    546   (int i,
    547    int* j);
    548 
    549 FOO_API int
    550 foo_qux
    551   (double d,
    552    int i);
    553 
    554 END_DECLS
    555 .Ed
    556 .\""""""""""""""""""""""""""""""""""
    557 .Ss Les symboles internes partagés
    558 Pour les fichiers d'en-tête internes au programme, utiliser la directive
    559 .Sy LOCAL_SYM ,
    560 définie dans le fichier
    561 .In rsys/rsys.h
    562 de la bibliothèque RSys, pour déclarer les variables globales et
    563 prototypes de fonctions.
    564 Ainsi leur symbole n'est pas exposé à l'extérieur du programme.
    565 .Bd -literal -offset Ds
    566 #include <rsys/rsys.h>
    567 
    568 extern LOCAL_SYM char bar[128];
    569 
    570 extern LOCAL_SYM void
    571 quux
    572   (char* tab,
    573    size_t length);
    574 .Ed
    575 .Pp
    576 Cette directive est redondante si le compilateur est configuré pour
    577 masquer par défaut tous les symboles
    578 .Po
    579 option
    580 .Fl fvisibility=hidden
    581 de
    582 .Xr gcc 1
    583 .Pc .
    584 Utiliser
    585 .Sy LOCAL_SYM
    586 permet néanmoins de s'exonérer de cet a priori, tout en uniformisant
    587 les déclaration des fonctions et variables où, pour chacune d'elles, la
    588 visibilité du symbole associé est alors explicite.
    589 .\""""""""""""""""""""""""""""""""""
    590 .Ss Les symboles internes à une unité de compilation
    591 Utiliser le mot clé
    592 .Ql static
    593 pour déclarer des variables constantes, et fonctions visibles uniquement
    594 au sein d'une unité de compilation.
    595 .Pp
    596 C'est notamment le cas de constantes symboliques structurée :
    597 .Bd -literal -offset Ds
    598 struct foo {
    599   int bar;
    600   int qux;
    601 };
    602 static const struct foo FOO_DEFAULT = {1, 0};
    603 .Ed
    604 .Pp
    605 Mais aussi des fonctions utilitaires, qu'elles soient
    606 propres à un fichier C, ou définies dans un fichier d'en-tête.
    607 .Bd -literal -offset Ds
    608 static void
    609 hello(void)
    610 {
    611   printf("Hello, world!\en");
    612 }
    613 .Ed
    614 .Pp
    615 Ces fonctions peuvent en plus être déclarées avec la directive
    616 .Sy INLINE ,
    617 définie dans l'en-tête
    618 .In rsys/rsys.h
    619 de la bibliothèque RSys,
    620 pour suggérer au compilateur de substituer l'appel de la fonction par le
    621 corps de celle-ci, de sorte à éviter le sur coût de l'appel.
    622 Cette directive est équivalente au mot clé
    623 .Sy inline
    624 du C99, indisponible dans le dialecte C retenu
    625 .Pq section Sx LE LANGAGE C .
    626 .Bd -literal -offset Ds
    627 static INLINE void
    628 foo(void)
    629 {
    630   printf("bar\en");
    631 }
    632 .Ed
    633 .Pp
    634 Limiter la directive
    635 .Sy INLINE
    636 aux fonctions élémentaires, destinées à être appelées fréquemment et
    637 dont le coût de l'appel pourrait alors s'avérer significatif.
    638 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    639 .Sh LES BLOCS
    640 Ouvrir chaque bloc sur la même ligne que la directive qui en est à
    641 l'origine
    642 .Po
    643 .Ql do ,
    644 .Ql enum
    645 .Ql for ,
    646 .Ql if ,
    647 .Ql struct ,
    648 .Ql switch ,
    649 .Ql union ,
    650 .Ql while
    651 .Pc ,
    652 en séparant par un espace la fin de la directive et le caractère
    653 .Ql {
    654 qui marque l'ouverture du bloc :
    655 .Bd -literal -offset Ds
    656 if (foo) {
    657   bar();
    658   qux();
    659 }
    660 .Ed
    661 .Pp
    662 Exception faite des fonctions, ou le bloc associé est ouvert sur la
    663 ligne qui suit :
    664 .Bd -literal -offset Ds
    665 static void
    666 foo(void)
    667 {
    668   printf("bar\en");
    669 }
    670 .Ed
    671 .Pp
    672 Fermer un bloc sur une ligne à part sauf s'il est suivi d'une nouvelle
    673 structure de contrôle associé à la précédente
    674 .Po
    675 .Ql if else ,
    676 .Ql do while
    677 .Pc .
    678 Dans ce cas, ajouter la nouvelle instruction sur la même ligne que celle
    679 utilisée pour fermer le bloc, en la séparant du caractère
    680 .Ql }
    681 par un espace.
    682 .Pp
    683 Aligner la fermeture du bloc à l'indentation de sa directive, ou, dans
    684 le cas de directives qui se suivent, de l'indentation de la première
    685 directive à l'origine des blocs successifs :
    686 .Bd -literal -offset Ds
    687 if (foo) {
    688   bar();
    689 } else {
    690   qux();
    691 }
    692 .Ed
    693 .Pp
    694 Écrire sur une seule ligne une directive et les opérations qu'elle
    695 contrôle que si la clarté du code n'en est pas impactée.
    696 Dans ce cas, l'ouverture et la fermeture du bloc associé se fait sur une
    697 seule et même ligne :
    698 .Bd -literal -offset Ds
    699 if (foo) { bar(); return 0; }
    700 .Ed
    701 .Pp
    702 Ne pas utiliser d'accolades si la structure de contrôle n'est suivie
    703 d'aucune ou d'une seule directive écrite sur la même ligne :
    704 .Bd -literal -offset Ds
    705 while (foo());
    706 
    707 if (bar) return 0;
    708 .Ed
    709 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    710 .Sh LES MOTS CLÉS
    711 Ajouter un espace après chaque structure de contrôle
    712 .Ql if ,
    713 .Ql switch ,
    714 .Ql for
    715 et
    716 .Ql while
    717 pour les différencier des appels de fonctions.
    718 Ne pas ajouter d'espace après l'ouverture et avant la fermeture des
    719 parenthèses qui détourent leur(s) expression(s) :
    720 .Bd -literal -offset Ds
    721 if (i < 10) {
    722   foo(i);
    723 }
    724 .Ed
    725 .Pp
    726 Ajouter un espace après chaque point virgule qui sépare les expressions
    727 d'une boucle
    728 .Ql for
    729 sauf si l'expression qui suit est vide :
    730 .Bd -literal -offset Ds
    731 for (i=0; i<10; foo(i++));
    732 
    733 for (;;) { /* Boucle infinie */
    734   poll();
    735   if(bar) break;
    736 }
    737 .Ed
    738 .Pp
    739 Assimiler l'instruction
    740 .Ql sizeof
    741 à une fonction ; ne pas insérer d'espace entre le mot clé et son
    742 expression entourée de parenthèses :
    743 .Bd -literal -offset Ds
    744 sz = sizeof(int);
    745 .Ed
    746 .\""""""""""""""""""""""""""""""""""
    747 .Ss L'instruction Ql switch
    748 Limiter à quelques lignes le contenu de chaque
    749 .Ql case
    750 d'une instruction
    751 .Ql switch ,
    752 celle-ci devant donner à lire la seule répartition des traitements,
    753 fonction de la valeur que peut prendre l'expression du
    754 .Ql switch .
    755 Et non les traitements eux même, sauf s'ils sont triviaux.
    756 Un
    757 .Ql case
    758 au contenu trop fourni est alors le signe d'un manque de structure dans
    759 l'écriture du programme.
    760 .Pp
    761 Toujours ajouter une instruction
    762 .Ql default
    763 même si l'ensemble des valeurs que pourraient prendre l'expression du
    764 .Ql switch
    765 est censé être couvert par les différents
    766 .Ql case .
    767 C'est notamment le cas quand l'expression est une variables de type
    768 .Vt enum .
    769 Utiliser alors la directive
    770 .Sy FATAL ,
    771 définie par la bibliothèque RSys
    772 .Pq en-tête In rsys/rsys.h ,
    773 pour signifier un comportement inattendu.
    774 Et ainsi pouvoir diagnostiquer une erreur dans la valeur de l'expression
    775 du
    776 .Ql switch ,
    777 ou un
    778 .Ql case
    779 manquant :
    780 .Bd -literal -offset Ds
    781 switch (i) {
    782   case FOO: foo(); break;
    783   case BAR: bar(); break;
    784   case QUX: qux = 1; break;
    785   default: FATAL("Unreachable code\en"); break;
    786 }
    787 .Ed
    788 .Pp
    789 Ajouter la directive
    790 .Sy FALLTHROUGH ,
    791 définie dans le fichier d'en-tête
    792 .In rsys/rsys.h
    793 de la bibliothèque RSys,
    794 en fin des instructions
    795 .Ql case
    796 qui s'enchaînent.
    797 L'ajout de cette directive permet d'expliciter que c'est bien le
    798 comportement attendu et non l'oublie d'une instruction
    799 .Ql break ,
    800 en plus d'éviter un possible message d'avertissement à la compilation
    801 .Pq option Fl Wimplicit-fallthrough No de Xr gcc 1 Ns
    802  :
    803 .Bd -literal -offset Ds
    804 switch (c) {
    805   case 'a':
    806     foo = 1;
    807     FALLTHROUGH;
    808   case 'b':
    809     bar = 1;
    810     break;
    811   default:
    812     usage();
    813     break;
    814 }
    815 .Ed
    816 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    817 .Sh LE NOMMAGE
    818 .Sh LES FONCTIONS
    819 .Sh LES VARIABLES
    820 .Sh LES CONSTANTES SYMBOLIQUES
    821 .Sh LES STRUCTURES
    822 .Sh LES MACROS
    823 .Sh LES ALLOCATIONS DYNAMIQUES
    824 .Sh LA GESTION DES ERREURS
    825 .Sh LES PROGRAMME EN LIGNE DE COMMANDE
    826 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    827 .Sh FICHIERS
    828 .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    829 .Sh VOIR AUSSI
    830 .Xr gcc 1 ,
    831 .Xr feature_test_macros 7
    832 .Pp
    833 .Rs
    834 .%A La Fondation pour le logiciel libre
    835 .%T Comment utiliser les licences GNU pour vos logiciels
    836 .%U https://www.gnu.org/licenses/gpl-howto.fr.html
    837 .Re