Modern C, édition C23
(gustedt.wordpress.com)- La version révisée de Modern C, alignée sur le nouveau standard C, est publiée en téléchargement gratuit, ce qui permet de revoir les ressources d’apprentissage et de référence du langage C selon C23
- La révision est centrée sur l’intégration de C23 et vise avant tout à accompagner la transition vers le nouveau standard en phase avec le calendrier et le processus de publication de l’ISO
- Les nouvelles versions des principaux compilateurs implémentent déjà la plupart des fonctionnalités de C23, si bien que les changements du livre vont au-delà d’une présentation expérimentale pour rejoindre un environnement d’usage réel
- Des évolutions du langage et de la bibliothèque comme
_BitInt(N),nullptr,auto,typeof,constexpr, etc. sont largement intégrées, avec un impact aussi sur les pratiques d’écriture du code C existant - Une annexe de transition et des en-têtes
includetemporaires ont été ajoutés pour permettre des essais immédiats sur les plateformes existantes, mais le MEAP de Manning est toujours en cours
Ressources gratuites et documentation du standard
- Modern C, édition C23 peut être téléchargé gratuitement
- Téléchargement : https://hal.inria.fr/hal-02383654
- Des ressources associées sont également disponibles sur la page dédiée au livre
- Page dédiée : https://gustedt.gitlabpages.inria.fr/modern-c/
- Cette page contient aussi le lien de téléchargement des exemples de code fournis avec le livre
- Cette édition révisée reprend plusieurs explications, mais son objectif principal est de refléter le nouveau standard du C, C23
- Parmi les documents en accès public, la ressource la plus proche du contenu du nouveau standard est le PDF N3220
- Les nouvelles versions des principaux compilateurs implémentent déjà la plupart des nouvelles fonctionnalités introduites par C23
Évolutions du langage C23 et support de transition
- Les changements liés aux entiers occupent une place importante
- Ajout du nouveau type à précision de bits
_BitInt(N) - Ajout de nouveaux en-têtes de la bibliothèque C pour l’arithmétique avec vérification de débordement et la manipulation de bits
- Prise en compte de la possibilité des types 128 bits sur les architectures modernes
- Y compris des améliorations concrètes des types enum
- Ajout du nouveau type à précision de bits
- Les autres nouveaux concepts de C23 sont également couverts
- La constante
nullptret le type sous-jacent associé - Les annotations syntaxiques via les attributes
- Des outils de programmation générique de types, dont
autoettypeof - L’initialisation par défaut avec
{}qui s’applique aussi aux tableaux de longueur variable constexprpour des constantes nommées de tous les types
- La constante
- Le nouveau contenu aborde aussi les expressions composées, les lambdas, l’« internationalisation » et jusqu’à une approche globale des défaillances de programme
- Une annexe et des en-têtes
includetemporaires ont été ajoutés pour permettre de démarrer immédiatement avec C23 sur les plateformes existantes - Le MEAP de la nouvelle édition chez Manning est toujours ouvert
- MEAP : https://www.manning.com/books/modern-c-third-edition
- La date de publication finale de l’édition C23 chez Manning n’est pas encore connue
1 commentaires
Commentaires sur Hacker News
Contrairement à l’endianness little-endian de stockage sur ma machine, la représentation où l’octet de poids fort vient d’abord s’appelle big-endian, mais dire que les deux sont encore couramment utilisés sur les processeurs modernes me semble un peu exagéré, car à part s390x, il n’en reste pratiquement plus
On dirait qu’un commentaire sur les architectures big-endian de niche / disparues, le préféré de tout le monde, va bientôt apparaître
Comme le disent d’autres commentaires bien classés, « moderne » ne veut pas forcément dire populaire ou largement utilisé
AIX et IBM i ne sont peut-être pas aussi actifs que les mainframes IBM, mais on peut dire qu’AIX est plus vivant que Solaris ou HP/UX, et encore davantage si on le compare aux nombreux Unix commerciaux d’autrefois. IBM i tient aussi encore le coup, mais il est bien plus vivant que des plateformes legacy midrange concurrentes comme HP MPE, dont le support éditeur a officiellement pris fin
L’aspect le plus important du C, c’est sa portabilité. L’idée est d’aller des petits microcontrôleurs à presque toutes les plateformes de calcul, donc on peut se demander si les nouvelles versions du C seront adoptées à ce point
Si je voulais utiliser l’état de l’art, je choisirais probablement C++2x ou Rust plutôt que C. Est-ce que je rate quelque chose ? Je me demande quels sont les avantages de ce soi-disant C moderne
Pour être à la pointe, je recommanderais Zig. La complexité du langage est bien plus faible que celle du C++ moderne et de Rust. Un effet secondaire positif, plus discret, de C23 est d’aligner davantage des syntaxes comme
... = {}et{0}sur le C++, ce qui rend la vie un peu moins pénible aux mainteneurs de bibliothèques C qui veulent prendre en charge ceux qui essaient de compiler leur code C avec un compilateur C++0best largement utilisée dans le monde des microcontrôleursLes toolchains pour microcontrôleurs sont en général construites sur GCC, donc elles récupèrent ces fonctionnalités gratuitement. Il reste toujours des compilateurs C propriétaires en retard, mais ils n’ont plus l’importance qu’ils avaient il y a 20 ans
À moins de viser l’embarqué ou un ensemble très large d’architectures, rien n’empêche d’utiliser C23 dès maintenant
thread_localest déjà utilisé sur certaines plateformes de microcontrôleurs, alors qu’avant C11 il était complètement illégal. Pourtant, il simplifie énormément la gestion mémoire dans les environnements multithreadY a-t-il vraiment une raison d’entrer dans l’univers du C++ juste pour ça ?
Personnellement, des choses comme
guard,defer,auto,constexpr,nullptrrendent le C beaucoup plus complexe. Si on choisit le C, c’est parce qu’on a besoin de simplicité ; si on voulait de la complexité, on choisirait en général du C++, même sans vraiment en avoir envie, ou alors Go, voire Elixir côté serveur_BitInt(N)est aussi assez laid, et fait heureusement penser à_Bool, qui est maintenantbool.constexpretnullptrsentent beaucoup trop le C++. Cela dit, Modern C est un excellent livre, et je m’en suis très bien servi pour du C99 que je compte continuer à utiliserNULL, la réponse se trouve en lisant la documentation pertinente, grâce à l’un des rares avantages de la normalisation ISO : https://wg21.link/p2312En résumé, passer
NULLcomme argument à une macro générique en type peut produire des résultats surprenants, et le statut d’expressions conditionnelles comme(1 ? 0 : NULL)et(1 ? 1 : NULL)varie selon la manière dontNULLest défini. De plus, passerNULLà une fonction variadique qui attend un pointeur peut avoir de graves conséquences. Sur beaucoup d’architectures modernes,intetvoid*n’ont pas la même taille ; siNULLn’est qu’un simple0, alors un argument de taille incorrecte est transmis à la fonctionC’est comme construire une maison. Un marteau et un tournevis sont très simples, tandis qu’une grue est extrêmement complexe, mais ce qui simplifie la construction d’une maison, c’est la grue. Si l’on devait construire une maison uniquement avec un marteau et un tournevis, il faudrait inventer une procédure incroyablement complexe
C’est pareil pour les langages de programmation. Créer des conteneurs génériques en C++ est trivial, alors qu’en C c’est très difficile. On peut l’imiter dans une certaine mesure avec
void *et des conversions manuelles, mais c’est fastidieux, sujet aux erreurs, et le code devient plus complexeC’est pareil pour
std::sortetqsort. Avec la puissance des templates et des foncteurs, l’implémentation est plus simple et plus rapide. Il n’est pas nécessaire de passer unvoid *ni de le déréférencer à l’exécution, et on peut intégrer la comparaison directement dans la définition de la fonction. Il n’y a ni appel indirect ni passage par la pile, et la fonction de comparaison peut même être inline. La complexité du langage ne signifie pas complexité d’implémentationautoest surtout utile quand on manipule des macros génériques en type, mais il vaut mieux éviter de l’utiliser dans le code ordinaire. J’espère qu’on évitera la folie du almost always auto qui a été à la mode pendant un temps dans le monde du C++Malheureusement, il y a encore de légères différences selon les compilateurs. Si je me souviens bien, Clang implémentait
autoà la manière du C++, tandis que GCC implémentaitautoà la manière du C, ce qui créait de subtiles différences pour les pointeursauto. Je ne sais pas si cela a été corrigé depuis_BitInt(N)ne s’utilise généralement pas directement ; on définit plutôt untypedefavec la largeur voulue. Par exemple :typedef _BitInt(2) u2;. Une syntaxe disgracieuse comme_Best nécessaire parce que les combinaisons underscore + majuscule sont réservées par la norme C, afin d’éviter les conflits avec du code existant lorsqu’on ajoute de petites fonctionnalités au langage._Boolporte ce nom pour la même raison. À ma connaissance,defern’est en fait pas entré dans C23L’ancienne définition ne précisait même pas si
NULLétait un pointeur ou un entier. Sur les plateformes qui ne respectaient pas l’exigence Posix de((void*)0), c’était donc un véritable piège, ni de type pointeur ni de taille pointeurSi
constexpretnullptront une odeur de C++, c’est probablement parce qu’ils ont été réimportés depuis le C++. On peut toutefois continuer à utiliserNULL, qui semble en apparence avoir été redéfini commenullptrexeclp("echo", "echo", "Hello, world!", NULL);Ce code n’a pas ce bug :
execlp("echo", "echo", "Hello, world!", nullptr);Celui-ci fonctionne aussi :
execlp("echo", "echo", "Hello, world!", (char *)NULL);J’allais demander s’il existait une bonne liste de livres sur le C, puis j’ai trouvé la réponse moi-même. Modern C y est classé comme intermédiaire
https://stackoverflow.com/questions/562303/the-definitive-c-...
Comme compagnon moderne de K&R pour le C, 21st Century C de Ben Klemens et C Programming: A Modern Approach de King me paraissent des alternatives plus accessibles
Personnellement, je préfère Effective C à Modern C. Modern C est extrêmement rigoureux ; pour un expert, cela peut être utile, mais pour quelqu’un comme moi qui utilise le C de façon assez légère, la lecture ressemble à celle d’une spécification annotée du langage et devient ennuyeuse
J’aime assez certaines des extensions High C de Metaware
https://news.ycombinator.com/item?id=41647843
https://news.ycombinator.com/item?id=38938402
Depuis plus d’un an, j’utilise le C++ moderne pour un projet personnel d’interpréteur de langage, mais la charge mentale du C++ et ses problèmes d’outillage me font sans cesse envisager un retour au C. L’IntelliSense de Visual Studio ne fonctionne toujours presque pas avec les modules C++20, et à cause des échecs du langage, bien trop de choses sont repoussées dans les interfaces, ce qui rend les temps de compilation hideux
À l’inverse, je me suis tellement habitué aux classes, aux fonctions membres, à la programmation générique et aux espaces de noms que j’ai peut-être déjà mordu à l’hameçon
Pour cet usage, as-tu envisagé le C# ? Visual Studio s’accorde bien mieux avec C#
Dans Preview sur macOS, cliquer sur les liens de table des matières dans la barre latérale ne fonctionne pas correctement
Cela ne fait que quelques années que, pour une bibliothèque que je maintiens, je peux considérer comme acquis que les compilateurs C prennent tous en charge le C99 : https://github.com/eyalroz/printf
Et pourtant, quelques années plus tard, un ticket a inévitablement été ouvert pour demander la compatibilité C89 à cause d’une antique toolchain embarquée. Donc oui, C23 c’est bien, mais j’ai un peu l’impression qu’on devrait en reparler dans 20 ans
Quelqu’un peut-il lier un article expliquant, d’un point de vue pratique, pourquoi le C est en réalité bloqué au C99 ? Il y a très peu de projets dignes d’être mentionnés qui utilisent des fonctionnalités postérieures au C11
Comme le C est resté de fait gelé pendant des décennies, sa base d’utilisateurs semble s’être auto-sélectionnée en faveur de gens qui aiment le C tel qu’il est et n’hésitent pas à supporter des compilateurs antiques et hétéroclites. Ceux qui ont perdu patience ou voulaient un langage du XXIe siècle sont partis vers le C++/Rust/Zig, etc.
Cela peut sembler étrange vu d’une époque où la plupart des développeurs semblent avoir migré vers Linux, mais vers 2010, MSVC était encore très important. En revanche, il n’existe pas tant de projets que ça qui ont absolument besoin des fonctionnalités du C11. Le C11 a aussi supprimé les VLA du C99, et ce n’était pas une grande perte. Le C23 est peut-être la première version depuis le C99 qui mérite réellement une mise à niveau pour beaucoup de bases de code C