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