Article de reference

Bibliothèque standard C

La bibliothèque standard C , parfois appelée libc , est la bibliothèque standard du langage de programmation C , telle que spécifiée dans la norme ISO C. À partir de la norme AN...

La bibliothèque standard C , parfois appelée libc , est la bibliothèque standard du langage de programmation C , telle que spécifiée dans la norme ISO C. À partir de la norme ANSI C d'origine , elle a été développée en même temps que la spécification POSIX de la bibliothèque C , qui en est un sur-ensemble. Depuis que l'ANSI C a été adopté par l' Organisation internationale de normalisation , la bibliothèque standard C est également appelée bibliothèque ISO C. [

La bibliothèque standard C fournit des macros , des définitions de type et des fonctions pour des tâches telles que la manipulation de chaînes , le calcul mathématique, le traitement des entrées/sorties, la gestion de la mémoire et les entrées/sorties .

Interface de programmation d'application (API)

Fichiers d'en-tête

L' interface de programmation d'application (API) de la bibliothèque standard C est déclarée dans un certain nombre de fichiers d'en-tête . Chaque fichier d'en-tête contient une ou plusieurs déclarations de fonction, définitions de type de données et macros.

Après une longue période de stabilité, trois nouveaux fichiers d'en-tête ( iso646.h, wchar.h, et wctype.h) ont été ajoutés avec l'Addendum Normatif 1 (NA1), un ajout à la norme C ratifié en 1995. Six autres fichiers d'en-tête ( complex.h, fenv.h, inttypes.h, stdbool.h, stdint.het tgmath.h) ont été ajoutés avec C99 , une révision de la norme C publiée en 1999, et cinq autres fichiers ( stdalign.h, stdatomic.h, stdnoreturn.h, threads.h, et uchar.h) avec C11 en 2011. Au total, il y a maintenant 29 fichiers d'en-tête :

Trois des fichiers d’en-tête ( complex.h, stdatomic.h, et threads.h) sont des fonctionnalités conditionnelles que les implémentations ne sont pas tenues de prendre en charge.

La norme POSIX a ajouté plusieurs en-têtes C non standard pour les fonctionnalités spécifiques à Unix. Beaucoup d'entre eux ont trouvé leur chemin vers d'autres architectures. Parmi les exemples, on peut citer fcntl.het unistd.h. Un certain nombre d'autres groupes utilisent d'autres en-têtes non standard : la bibliothèque C GNU possède alloca.h, et OpenVMS possède la va_count()fonction .

Documentation

Sur les systèmes de type Unix, la documentation officielle de l'API est fournie sous la forme de pages de manuel . Sur la plupart des systèmes, les pages de manuel sur les fonctions de la bibliothèque standard se trouvent dans la section 3 ; la section 7 peut contenir des pages plus génériques sur les concepts sous-jacents (par exemple man 7 math_errorsous Linux ).

Implémentations

Les systèmes de type Unix disposent généralement d'une bibliothèque C sous forme de bibliothèque partagée , mais les fichiers d'en-tête (et la chaîne d'outils du compilateur) peuvent être absents d'une installation, ce qui rend le développement en C impossible. La bibliothèque C est considérée comme faisant partie du système d'exploitation sur les systèmes de type Unix ; en plus des fonctions spécifiées par la norme C, elle comprend d'autres fonctions qui font partie de l'API du système d'exploitation, telles que les fonctions spécifiées dans la norme POSIX . Les fonctions de la bibliothèque C, y compris celles de la norme ISO C, sont largement utilisées par les programmes et sont considérées comme si elles n'étaient pas seulement une implémentation de quelque chose dans le langage C, mais aussi une partie de facto de l'interface du système d'exploitation. Les systèmes d'exploitation de type Unix ne peuvent généralement pas fonctionner si la bibliothèque C est effacée. Cela est vrai pour les applications qui sont liées de manière dynamique plutôt que statique. De plus, le noyau lui-même (au moins dans le cas de Linux) fonctionne indépendamment de toute bibliothèque.

Sous Microsoft Windows, les bibliothèques dynamiques du système principal ( DLL ) fournissent une implémentation de la bibliothèque standard C pour le compilateur Microsoft Visual C++ v6.0 ; la bibliothèque standard C pour les versions plus récentes du compilateur Microsoft Visual C++ est fournie par chaque compilateur individuellement, ainsi que par des packages redistribuables . Les applications compilées écrites en C sont soit liées statiquement à une bibliothèque C, soit liées à une version dynamique de la bibliothèque fournie avec ces applications, plutôt que d'être censées être présentes sur les systèmes ciblés. Les fonctions de la bibliothèque C d'un compilateur ne sont pas considérées comme des interfaces avec Microsoft Windows.

Il existe de nombreuses implémentations de bibliothèques C, fournies avec différents systèmes d'exploitation et compilateurs C. Certaines des implémentations les plus populaires sont les suivantes :

  • La bibliothèque BSD libc , diverses implémentations distribuées avec les systèmes d'exploitation dérivés de BSD
  • Bibliothèque GNU C (glibc), utilisée dans GNU Hurd , GNU/kFreeBSD et la plupart des distributions Linux
  • Bibliothèque d'exécution Microsoft C , qui fait partie de Microsoft Visual C++ . Il existe deux versions de la bibliothèque : MSVCRT qui était redistribuable jusqu'à la version 12/Visual Studio 2013 avec une faible conformité C99, et une nouvelle UCRT (Universal C Run Time) qui fait partie de Windows 10 et 11, donc toujours présente pour établir un lien, et qui est également conforme C99 [1].
  • dietlibc , une petite implémentation alternative de la bibliothèque standard C (sans MMU)
  • μClibc , une bibliothèque standard C pour les systèmes μClinux embarqués (sans MMU)
  • Newlib , une bibliothèque standard C pour les systèmes embarqués (sans MMU) et utilisée dans la distribution Cygwin GNU pour Windows
  • klibc , principalement pour démarrer les systèmes Linux
  • musl , une autre implémentation légère de la bibliothèque standard C pour les systèmes Linux
  • Bionic , développé à l'origine par Google pour le système d'exploitation embarqué Android, dérivé de BSD libc
  • picolibc, développé par Keith Packard , ciblant les petits systèmes embarqués avec une RAM limitée, basé sur le code de Newlib et AVR Libc

Fonctions intégrées au compilateur

Certains compilateurs (par exemple, GCC ) fournissent des versions intégrées de nombreuses fonctions de la bibliothèque standard C ; c'est-à-dire que les implémentations des fonctions sont écrites dans le fichier objet compilé et le programme appelle les versions intégrées au lieu des fonctions du fichier objet partagé de la bibliothèque C. Cela réduit la charge des appels de fonction, en particulier si les appels de fonction sont remplacés par des variantes en ligne , et permet d'autres formes d' optimisation (car le compilateur connaît les caractéristiques de flux de contrôle des variantes intégrées), mais peut entraîner une confusion lors du débogage (par exemple, les versions intégrées ne peuvent pas être remplacées par des variantes instrumentées ).

Cependant, les fonctions intégrées doivent se comporter comme des fonctions ordinaires conformément à la norme ISO C. La principale implication est que le programme doit être capable de créer un pointeur vers ces fonctions en prenant leur adresse et d'invoquer la fonction au moyen de ce pointeur. Si deux pointeurs vers la même fonction sont dérivés de deux unités de traduction différentes dans le programme, ces deux pointeurs doivent être équivalents ; c'est-à-dire que l'adresse provient de la résolution du nom de la fonction, qui a un lien externe (à l'échelle du programme).

Lien, libm

Sous FreeBSD et glibc, certaines fonctions telles que sin() ne sont pas liées par défaut et sont plutôt regroupées dans la bibliothèque mathématique libm . Si l'une d'entre elles est utilisée, le linker doit recevoir la directive -lm. POSIX exige que le compilateur c99 prenne en charge -lm, et que les fonctions déclarées dans les en-têtes math.h, complex.h, et fenv.hsoient disponibles pour la liaison si -lmest spécifié, mais ne précise pas si les fonctions sont liées par défaut. musl satisfait cette exigence en mettant tout dans une seule bibliothèque libc et en fournissant une libm vide.

Détection

Selon la norme C, la macro __STDC_HOSTED__doit être définie à 1 si l'implémentation est hébergée. Une implémentation hébergée possède tous les en-têtes spécifiés par la norme C. Une implémentation peut également être autonome, ce qui signifie que ces en-têtes ne seront pas présents. Si une implémentation est autonome , elle doit être définie __STDC_HOSTED__à 0 .

Problèmes et solutions de contournement

Vulnérabilités de dépassement de tampon

Certaines fonctions de la bibliothèque standard C sont connues pour présenter des vulnérabilités de dépassement de mémoire tampon et pour encourager une programmation boguée depuis leur adoption. Les éléments les plus critiqués sont :

À l'exception du cas extrême avec gets(), toutes les vulnérabilités de sécurité peuvent être évitées en introduisant du code auxiliaire pour effectuer la gestion de la mémoire, la vérification des limites, la vérification des entrées, etc. Cela se fait souvent sous la forme de wrappers qui rendent les fonctions de la bibliothèque standard plus sûres et plus faciles à utiliser. Cela remonte au livre The Practice of Programming de B. Kernighan et R. Pike, où les auteurs utilisent couramment des wrappers qui impriment des messages d'erreur et quittent le programme si une erreur se produit.

Le comité ISO C a publié les rapports techniques TR 24731-1 et travaille sur le TR 24731-2 pour proposer l'adoption de certaines fonctions avec vérification des limites et allocation automatique de tampons, en conséquence. Le premier a rencontré de vives critiques avec quelques éloges, et le second a reçu des réponses mitigées.

Malgré les inquiétudes, la norme TR 24731-1 a été intégrée dans la piste de normes C de la norme ISO/IEC 9899:2011 (C11), Annexe K ( Interfaces de vérification des limites ), et implémentée approximativement dans la bibliothèque d'exécution C/++ (CRT) de Microsoft pour les plates-formes Win32 et Win64.

(Par défaut, les compilateurs C et C++ de Microsoft Visual Studio émettent des avertissements lors de l'utilisation de fonctions plus anciennes et « non sécurisées ». Cependant, l'implémentation de TR 24731-1 par Microsoft est subtilement incompatible avec TR 24731-1 et l'annexe K, il est donc courant que les projets portables désactivent ou ignorent ces avertissements. Ils peuvent être désactivés directement en émettant

#pragma warning(désactiver : 4996)

avant/autour du ou des sites d'appel en question, ou indirectement en émettant

#define _CRT_SECURE_NO_WARNINGS 1

avant d'inclure des en-têtes. L'option de ligne de commande /D_CRT_NO_SECURE_WARNINGS=1devrait avoir le même effet que cela #define.)

Problèmes de threading, vulnérabilité aux conditions de course

La strerror()routine est critiquée pour son caractère non sécurisé au niveau des threads et pour sa vulnérabilité aux conditions de concurrence .

Gestion des erreurs

La gestion des erreurs des fonctions dans la bibliothèque standard C n'est pas cohérente et parfois déroutante. Selon la page de manuel Linux math_error, « La situation actuelle (version 2.8) sous glibc est compliquée. La plupart des fonctions (mais pas toutes) génèrent des exceptions en cas d'erreur. Certaines définissent également errno . Quelques fonctions définissent errno , mais ne génèrent pas d'exception. Un très petit nombre de fonctions ne font ni l'un ni l'autre. »

Standardisation

Le langage C original ne proposait aucune fonction intégrée telle que les opérations d'E/S, contrairement aux langages traditionnels tels que COBOL et Fortran . Au fil du temps, les communautés d'utilisateurs de C ont partagé des idées et des implémentations de ce que l'on appelle aujourd'hui les bibliothèques standard C. Bon nombre de ces idées ont finalement été incorporées dans la définition du langage C standardisé.

Unix et C ont été créés dans les laboratoires Bell d'AT&T à la fin des années 1960 et au début des années 1970. Au cours des années 1970, le langage C est devenu de plus en plus populaire. De nombreuses universités et organisations ont commencé à créer leurs propres variantes du langage pour leurs propres projets. Au début des années 1980, des problèmes de compatibilité entre les différentes implémentations du C sont devenus apparents. En 1983, l' American National Standards Institute (ANSI) a formé un comité pour établir une spécification standard du C connue sous le nom de « ANSI C ». Ce travail a abouti à la création de la norme dite C89 en 1989. Une partie de la norme résultante était un ensemble de bibliothèques logicielles appelées bibliothèque standard ANSI C.

Bibliothèque standard POSIX

POSIX , ainsi que SUS , spécifient un certain nombre de routines qui devraient être disponibles en plus de celles de la bibliothèque standard C de base. La spécification POSIX inclut des fichiers d'en-tête pour, entre autres utilisations, le multithreading , la mise en réseau et les expressions régulières . Ceux-ci sont souvent implémentés parallèlement aux fonctionnalités de la bibliothèque standard C, avec des degrés de proximité variables. Par exemple, glibc implémente des fonctions telles que forkwithin libc.so, mais avant que NPTL ne soit fusionné avec glibc, il constituait une bibliothèque séparée avec son propre argument d'indicateur de lien. Souvent, cette fonctionnalité spécifiée par POSIX sera considérée comme faisant partie de la bibliothèque ; la bibliothèque C de base peut être identifiée comme la bibliothèque C ANSI ou ISO .

Bibliothèque BSD

La bibliothèque BSD libc est un sur-ensemble de la bibliothèque standard POSIX prise en charge par les bibliothèques C incluses dans les systèmes d'exploitation BSD tels que FreeBSD , NetBSD , OpenBSD et macOS . La bibliothèque BSD libc comporte des extensions qui ne sont pas définies dans la norme d'origine, dont beaucoup sont apparues pour la première fois dans la version 4.4BSD de 1994 (la première à être largement développée après la publication de la première norme en 1989). Certaines des extensions de la bibliothèque BSD libc sont :

  • sys/tree.h – contient une implémentation de l'arbre rouge-noir et de l'arbre étalé
  • sys/queue.h – implémentations de listes chaînées , de files d'attente , de files d'attente de queue, etc.
  • fgetln() – défini dans stdio.h. Cela peut être utilisé pour lire un fichier ligne par ligne.
  • fts.h – contient certaines fonctions permettant de parcourir une hiérarchie de fichiers
  • db.h – quelques fonctions pour se connecter à la base de données Berkeley DB
  • strlcat()et strlcpy() – alternatives sûres pour strncat()et strncpy()
  • err.h – contient certaines fonctions pour imprimer des messages d’erreur formatés
  • vis.h – contient la vis()fonction. Cette fonction permet d'afficher des caractères non imprimables dans un format visuel.

La bibliothèque standard C dans d'autres langages

Certains langages incluent les fonctionnalités de la bibliothèque C standard dans leurs propres bibliothèques. La bibliothèque peut être adaptée pour mieux correspondre à la structure du langage, mais la sémantique opérationnelle reste similaire.

C++

Le langage C++ intègre la majorité des constructions de la bibliothèque standard C dans les siennes, à l'exclusion des machines spécifiques à C. Les fonctions de la bibliothèque standard C++ sont exportées depuis la bibliothèque standard C++ de deux manières.

Pour la compatibilité ascendante/croisée avec C et le C++ pré-standard, les fonctions peuvent être accessibles dans l' espace de noms global ( :: ), après avoir inséré le nom d'en-tête standard C comme dans C. Ainsi, le programme C++98#include

#include <stdio.h> int main () { return :: puts ( "Bonjour tout le monde !" ) == EOF ; }

devrait présenter un comportement (apparemment) identique au programme C95

#include <stdio.h> int main ( void ) { return puts ( "Bonjour tout le monde !" ) == EOF ; }

À partir de C++98 , les fonctions C sont également disponibles dans l'espace de noms ::std (par exemple, C printf en tant que C++ ::std::printf , atoi en tant que ::std::atoi , feof en tant que ::std::feof ), en incluant header au lieu de l'en-tête C correspondant . Par exemple, <cstdio> remplace <stdio.h> et <cmath> remplace <math.h> ; notez l'absence d' extension .h sur les noms d'en-tête C++. <chdrname><hdrname.h>

Ainsi, un programme C++≥98 équivalent (généralement préférable) aux deux ci-dessus est :

#include <cstdio> int main () { return std :: puts ( "Bonjour, tout le monde" ) == EOF ; }

Une déclaration au-dessus ou dans main peut être émise pour appliquer automatiquement le préfixe ::std:: , bien qu'il soit généralement considéré comme une mauvaise pratique de l'utiliser globalement dans les en-têtes car cela pollue l'espace de noms global. usingnamespace::std

Quelques-unes des versions C++≥98 des en-têtes de C sont manquantes ; par exemple, C≥11 <stdnoreturn.h> et <threads.h> n'ont pas d'équivalents C++.

D'autres sont réduits à des espaces réservés, comme (jusqu'à C++20 ) <ciso646> pour C95 <iso646.h> , dont toutes les macros requises sont rendues sous forme de mots-clés dans C++98. Les constructions syntaxiques spécifiques à C ne sont généralement pas prises en charge, même si leur en-tête l'est.

Plusieurs en-têtes C existent principalement pour la compatibilité C++, et ils ont tendance à être presque vides en C++. Par exemple, C9917 <stdbool.h> ne nécessitent que

#define bool _Bool 
#define false 0 
#define true 1 
#define __bool_true_false_are_defined 1

afin de simuler la prise en charge des mots-clés bool , false et true de C++98 en C. C++11 requiert <stdbool.h> et <cstdbool> pour la compatibilité, mais tout ce qu'ils doivent définir est __bool_true_false_are_defined . C23 rend obsolète l'ancien mot-clé _Bool en faveur des nouveaux mots-clés bool , false et true équivalents à C++98 , de sorte que les en-têtes <stdbool.h> / <cstdbool> de C≥23 et C++≥11 sont totalement équivalents. (En particulier, C23 ne nécessite aucune macro __STDC_VERSION_BOOL_H__ pour <stdbool.h> .)

L'accès aux fonctions de la bibliothèque C via l'espace de noms ::std et les noms d'en-tête C++≥98 est préféré lorsque cela est possible. Pour encourager l'adoption, C++98 rend obsolètes les noms d'en-tête C ( *.h ), il est donc possible que l'utilisation d'en-têtes de compatibilité C amène un préprocesseur C++98–20 particulièrement strict à générer un diagnostic quelconque. Cependant, C++23 (de manière inhabituelle) rend obsolètes ces en-têtes, de sorte que les implémentations/modes C++ plus récents ne devraient pas se plaindre sans y être spécifiquement invités.


D'autres langages adoptent une approche similaire, en plaçant les fonctions/routines de compatibilité C sous un espace de noms commun ; il s'agit notamment de D , Perl et Ruby .

Python

CPython inclut des wrappers pour certaines des fonctions de la bibliothèque C dans sa propre bibliothèque commune, et il accorde également un accès plus direct aux fonctions et variables C via son package ctypes

Plus généralement, Python 2. x spécifie les objets de fichiers intégrés comme étant « implémentés à l'aide du package stdio de C », et une référence fréquente est faite aux comportements de la bibliothèque standard C ; les opérations disponibles ( open, read, write, etc.) sont censées avoir le même comportement que les fonctions C correspondantes ( fopen, fread, fwrite, etc.).

Cependant, les spécifications de Python 3 s’appuient beaucoup moins sur les spécificités de C que celles de Python 2 .

Rouiller

Rust propose crate libc , qui permet d'utiliser diverses fonctions de bibliothèque standard C (et autres) et définitions de type.

Comparaison avec les bibliothèques standards d'autres langages

La bibliothèque standard C est petite par rapport aux bibliothèques standard de certains autres langages. La bibliothèque C fournit un ensemble de base de fonctions mathématiques, de manipulation de chaînes, de conversions de types et d'E/S basées sur des fichiers et des consoles. Elle n'inclut pas d'ensemble standard de « types de conteneurs » comme la bibliothèque de modèles standard C++ , sans parler des boîtes à outils complètes d'interface utilisateur graphique (GUI), des outils réseau et de la profusion d'autres fonctionnalités que Java et le .NET Framework fournissent en standard. Le principal avantage de la petite bibliothèque standard est que fournir un environnement ISO C fonctionnel est beaucoup plus facile qu'avec d'autres langages, et par conséquent, porter C sur une nouvelle plate-forme est relativement facile.

Plus d articles de Worldlex Wiki

Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

Explorer l index