Standardní knihovna C - C standard library

Standardní knihovny C nebo libc je standardní knihovna pro programovací jazyk C , jak je uvedeno v ISO C standard. Počínaje původním standardem ANSI C byl vyvinut ve stejnou dobu jako specifikace C knihovny POSIX , která je jeho nadmnožinou. Vzhledem k tomu, ANSI C byl přijat Mezinárodní organizace pro normalizaci , standardní knihovny C je také nazýván knihovnu ISO C .

Standardní knihovna C poskytuje makra , definice typů a funkce pro úkoly, jako je zpracování řetězců , matematické výpočty, zpracování vstupu/výstupu, správa paměti a několik dalších služeb operačního systému .

Rozhraní pro programování aplikací

Soubory záhlaví

Aplikační programovací rozhraní (API) ze standardní knihovny jazyka C je deklarována v několika hlavičkových souborů . Každý soubor záhlaví obsahuje jednu nebo více deklarací funkcí, definice datových typů a makra.

Po dlouhém období stability, tři nové soubory s hlavičkou ( iso646.h, wchar.h, a wctype.h) byly přidány s normativní dodatku 1 (NA1), která je navíc k C standardu ratifikované v roce 1995. Six (další hlavičkové soubory complex.h, fenv.h, inttypes.h, stdbool.h, stdint.h, a tgmath.h) se přidá s C99 , revize na C standardu zveřejněného v roce 1999, a pět dalších souborů ( stdalign.h, stdatomic.h, stdnoreturn.h, threads.ha uchar.h) s C11 v roce 2011 celkem, v současné době existuje 29 hlavičkové soubory:

název Z Popis
<assert.h> Obsahuje makro assert , které slouží k detekci logických chyb a dalších typů chyb při ladění verzí programu.
<complex.h> C99 Sada funkcí pro manipulaci s komplexními čísly .
<ctype.h> Definuje sadu funkcí používaných ke klasifikaci znaků podle jejich typů nebo k převodu mezi velkými a malými písmeny způsobem, který je nezávislý na použité znakové sadě (obvykle ASCII nebo jedno z jejích rozšíření, i když jsou známy i implementace využívající EBCDIC ).
<errno.h> Pro testování chybových kódů hlášených funkcemi knihovny.
<fenv.h> C99 Definuje sadu funkcí pro ovládání prostředí s plovoucí desetinnou čárkou .
<float.h> Definuje konstanty makra určující vlastnosti specifické pro implementaci knihovny s pohyblivou řádovou čárkou .
<inttypes.h> C99 Definuje celočíselné typy přesné šířky .
<iso646.h> NA1 Definuje několik maker, která implementují alternativní způsoby vyjádření několika standardních tokenů. Pro programování ve variantních znakových sadách ISO 646 .
<limits.h> Definuje konstanty makra určující vlastnosti specifické pro implementaci celočíselných typů.
<locale.h> Definuje lokalizační funkce .
<math.h> Definuje běžné matematické funkce .
<setjmp.h> Deklaruje makra setjmpa longjmp, která se používají pro nelokální východy.
<signal.h> Definuje funkce zpracování signálu .
<stdalign.h> C11 Pro dotazování a zadávání zarovnání objektů.
<stdarg.h> Pro přístup k měnícímu se počtu argumentů předaných funkcím.
<stdatomic.h> C11 Pro atomické operace s daty sdílenými mezi vlákny.
<stdbool.h> C99 Definuje logický datový typ .
<stddef.h> Definuje několik užitečných typů a maker .
<stdint.h> C99 Definuje celočíselné typy přesné šířky .
<stdio.h> Definuje základní vstupní a výstupní funkce
<stdlib.h> Definuje funkce numerická konverze , funkce čísla generace pseudonáhodných , přidělování paměti , řízení procesů funkce
<stdnoreturn.h> C11 Pro specifikaci nevracejících se funkcí
<string.h> Definuje funkce zpracování řetězců
<tgmath.h> C99 Definuje typově obecné matematické funkce .
<threads.h> C11 Definuje funkce pro správu více vláken , mutexů a proměnných podmínek
<time.h> Definuje funkce zpracování data a času
<uchar.h> C11 Typy a funkce pro manipulaci se znaky Unicode
<wchar.h> NA1 Definuje funkce zpracování širokých řetězců
<wctype.h> NA1 Definuje sadu funkcí používaných ke klasifikaci širokých znaků podle jejich typů nebo k převodu mezi velkými a malými písmeny

Tři z hlavičkových souborů ( complex.h, stdatomic.h, a threads.h) jsou podmíněné funkce, které implementace se nevyžaduje podporu.

Standard POSIX přidal několik nestandardních záhlaví C pro funkce specifické pro Unix. Mnozí si našli cestu do jiných architektur. Mezi příklady patří fcntl.ha unistd.h. Řada dalších skupin používá jiná nestandardní záhlaví - GNU C Libraryalloca.ha HP OpenVMS tuto va_count()funkci má .

Dokumentace

V systémech podobných Unixu je autoritativní dokumentace skutečně implementovaného API poskytována ve formě manuálových stránek . Ve většině systémů jsou manuálové stránky o standardních funkcích knihovny v sekci 3; část 7 může obsahovat obecnější stránky o základních pojmech (např. man 7 math_errorv Linuxu ).

Implementace

Unixové systémy mají obvykle knihovnu C ve formě sdílené knihovny , ale soubory záhlaví (a kompilátor nástrojů) v instalaci nemusí chybět, takže vývoj C nemusí být možný. Knihovna C je v unixových systémech považována za součást operačního systému. Funkce C, včetně standardních funkcí ISO C, jsou široce používány programy a jsou považovány za nejen jako implementaci něčeho v jazyce C, ale také de facto jako součást rozhraní operačního systému. Unixové operační systémy obecně nemohou fungovat, pokud je vymazána knihovna C. To platí pro aplikace, které jsou dynamicky na rozdíl od staticky propojených. Kromě toho samotné jádro (alespoň v případě Linuxu) funguje nezávisle na jakýchkoli knihovnách.

V systému Microsoft Windows poskytují dynamické knihovny ( DLL ) jádra implementaci standardní knihovny C pro kompilátor Microsoft Visual C ++ v6.0; standardní knihovnu C pro novější verze kompilátoru Microsoft Visual C ++ poskytuje každý kompilátor samostatně, stejně jako redistribuovatelné balíčky. Kompilované aplikace napsané v jazyce C jsou buď staticky propojeny s knihovnou C, nebo propojeny s dynamickou verzí knihovny, která je dodávána s těmito aplikacemi, než aby se spoléhaly na přítomnost v cílených systémech. Funkce v knihovně C kompilátoru nejsou považovány za rozhraní pro Microsoft Windows.

Existuje mnoho dalších implementací, dodávaných s různými operačními systémy i kompilátory C. Některé z populárních implementací jsou následující:

Integrované funkce kompilátoru

Některé překladače (například GCC ) poskytují vestavěné verze mnoha funkcí ve standardní knihovně C; to znamená, že implementace těchto funkcí jsou zapsány do sestaveného souboru objektu a program volá vestavěná verze namísto funkce v C knihovny sdíleného objektu souboru. To snižuje režii volání funkce, zvláště pokud jsou volání funkcí nahrazena vloženými variantami, a umožňuje další formy optimalizace (protože kompilátor zná charakteristiky řídicího toku vestavěných variant), ale může způsobit zmatek při ladění (například , vestavěné verze nelze nahradit přístrojovými variantami).

Vestavěné funkce se však musí chovat jako běžné funkce v souladu s ISO C. Hlavním důsledkem je, že program musí být schopen vytvořit ukazatel na tyto funkce tak, že vezme jejich adresu a vyvolá funkci pomocí tohoto ukazatele. Pokud jsou dva ukazatele na stejnou funkci odvozeny ve dvou různých translačních jednotkách v programu, musí se tyto dva ukazatele porovnávat stejně; to znamená, že adresa přichází přeložením názvu funkce, která má externí (v rámci celého programu) propojení.

Propojení, libm

V rámci FreeBSD a glibc nejsou některé funkce, jako například sin () ve výchozím nastavení propojeny, a místo toho jsou sdruženy v matematické knihovně libm . Pokud jsou použity některé z nich, musí mít linker uvedenou směrnici -lm. POSIX vyžaduje, aby C99 kompilátor podporuje -lm, a že funkce deklarované v záhlaví math.h, complex.ha fenv.hjsou k dispozici pro propojení, pokud -lmje specifikována, ale neupřesňuje, v případě, že funkce jsou ve výchozím nastavení propojen. musl splňuje tento požadavek vložením všeho do jediné knihovny libc a poskytnutím prázdného libm.

Detekce

Podle standardu C bude makro __STDC_HOSTED__definováno na 1, pokud je implementace hostována. Hostovaná implementace má všechna záhlaví určená standardem C. Implementace může být také volně stojící, což znamená, že tyto záhlaví nebudou k dispozici. Pokud je implementace volně stojící , definuje se __STDC_HOSTED__na 0 .

Problémy a řešení

Zranitelnost přetečení vyrovnávací paměti

Některé funkce ve standardní knihovně C jsou proslulé tím, že mají chyby v přetečení vyrovnávací paměti a obecně podporují buggy programování od jejich přijetí. Nejkritičtější položky jsou:

  • rutiny manipulace s řetězci , včetně strcpy()a strcat(), pro nedostatek kontroly mezí a možného přetečení vyrovnávací paměti, pokud nejsou hranice kontrolovány ručně;
  • řetězcové rutiny obecně, pro vedlejší efekty , podporující nezodpovědné použití vyrovnávací paměti, ne vždy zaručující platný výstup zakončený nulou , lineární výpočet délky;
  • printf()rodina rutin, která kazí vykonávací zásobník, když formátovací řetězec neodpovídá zadaným argumentům. Tato zásadní chyba vytvořila celou třídu útoků: útoky formátovacích řetězců ;
  • gets()a scanf()řada I/O rutin, kvůli nedostatku kontroly (buď jakékoli, nebo snadné) vstupní délky.

S výjimkou extrémních případů gets()lze všem zranitelnostem zabezpečení zabránit zavedením pomocného kódu pro správu paměti, kontrolu hranic, kontrolu vstupů atd. To se často provádí ve formě obalů, díky nimž jsou standardní funkce knihovny bezpečnější a snadněji se používají. To se datuje už od knihy B.

Výbor ISO C publikoval technické zprávy TR 24731-1 a pracuje na TR 24731-2, aby odpovídajícím způsobem navrhl přijetí některých funkcí s kontrolou mezí a automatickým přidělováním vyrovnávací paměti. První z nich se setkal s vážnou kritikou s určitou chválou, druhý obdržel smíšené reakce. Navzdory tomu byl TR 24731-1 implementován do standardní knihovny Microsoft C a jeho kompilátor vydává varování při používání starých „nezabezpečených“ funkcí.

Problémy se závity, zranitelnost vůči závodním podmínkám

strerror()Rutina je kritizována za to, že nit nebezpečné a jinak citlivé na podmínky závodu .

Vypořádání se s chybou

Zpracování chyb funkcí ve standardní knihovně C není konzistentní a někdy matoucí. Podle manuálové stránky Linuxu math_error„Aktuální situace (verze 2.8) pod glibc je chaotická. Většina (ale ne všechny) funkce vyvolávají výjimky z chyb. Některé také nastavují errno . Několik funkcí nastavuje errno , ale nevyvolává výjimku "Velmi málo funkcí ne."

Standardizace

Původní jazyk C neposkytoval žádné vestavěné funkce, jako jsou I/O operace, na rozdíl od tradičních jazyků, jako jsou COBOL a Fortran . Uživatelské komunity C v průběhu času sdílely nápady a implementace toho, čemu se nyní říká standardní knihovny C. Mnoho z těchto myšlenek bylo nakonec začleněno do definice standardizovaného jazyka C.

Oba Unix a C byly vytvořeny v AT & T Bell Laboratories v pozdní 1960 a brzy 1970. V sedmdesátých letech byl jazyk C stále oblíbenější. Mnoho univerzit a organizací začalo vytvářet vlastní varianty jazyka pro své vlastní projekty. Na začátku 80. let se začaly projevovat problémy s kompatibilitou mezi různými implementacemi C. V roce 1983 Americký národní normalizační institut (ANSI) vytvořil výbor pro stanovení standardní specifikace C známé jako „ ANSI C “. Tato práce vyvrcholila vytvořením takzvaného standardu C89 v roce 1989. Součástí výsledného standardu byla sada softwarových knihoven nazývaných standardní knihovna ANSI C.

Standardní knihovna POSIX

POSIX , stejně jako SUS , určují řadu rutin, které by měly být k dispozici nad rámec standardní knihovny standardního jazyka C. Specifikace POSIX obsahuje soubory záhlaví, mimo jiné pro vícevláknové , síťové a regulární výrazy . Ty jsou často implementovány společně s funkcí standardní knihovny C, s různým stupněm blízkosti. Například glibc implementuje funkce, jako například forkuvnitř libc.so, ale předtím, než byl NPTL sloučen do glibc, představoval samostatnou knihovnu s vlastním argumentem příznaku linkeru. Tato funkce specifikovaná pro POSIX bude často považována za součást knihovny; základní knihovnu C lze identifikovat jako knihovnu ANSI nebo ISO C.

BSD libc

BSD libc je nadmnožinou standardní knihovny POSIX podporované knihovnami C obsaženými v operačních systémech BSD, jako jsou FreeBSD , NetBSD , OpenBSD a macOS . BSD libc má některá rozšíření, která nejsou definována v původním standardu, z nichž mnohé se poprvé objevily ve verzi 4.4BSD z roku 1994 (první, která byla do značné míry vyvinuta po vydání prvního standardu v roce 1989). Některá z rozšíření BSD libc jsou:

  • sys/tree.h - obsahuje implementaci červeno -černého stromu a splay stromu
  • sys/queue.h - implementace propojeného seznamu , front , ocasních front atd.
  • fgetln() - definováno v stdio.h. To lze použít ke čtení souboru řádek po řádku.
  • fts.h - obsahuje některé funkce pro procházení hierarchie souborů
  • db.h - některé funkce pro připojení k Berkeley DB
  • strlcat()a strlcpy() - zabezpečit alternativy pro strncat()astrncpy()
  • err.h - obsahuje některé funkce pro tisk formátovaných chybových zpráv
  • vis.h - obsahuje vis()funkci. Tato funkce se používá k zobrazení netisknutelných znaků ve vizuálním formátu.

Standardní knihovna C v jiných jazycích

Některé jazyky obsahují funkce standardní knihovny C ve svých vlastních knihovnách. Knihovna může být přizpůsobena tak, aby lépe vyhovovala jazykové struktuře, ale operační sémantika je zachována podobně. V C ++ jazyka, například, zahrnuje funkce C standardní knihovny v jmenném prostoru std (například std::printf, std::atoi, std::feof), v hlavičkové soubory s podobnými názvy těm C ( cstdio, cmath, cstdlibatd.) Dalšími jazyky, které používají podobné přístupy, jsou D , Perl , Ruby a hlavní implementace Pythonu známá jako CPython . V Pythonu 2 jsou například vestavěné objekty souborů definovány jako „implementované pomocí stdiobalíčku C “, takže se očekává, že dostupné operace (otevírání, čtení, zápis atd.) Budou mít stejné chování jako odpovídající funkce C . Rust má bednu s názvem libc, která umožňuje použití několika C funkcí, struktur a dalších definic typů.

Srovnání se standardními knihovnami jiných jazyků

Standardní knihovna C je malá ve srovnání se standardními knihovnami některých jiných jazyků. Knihovna C poskytuje základní sadu matematických funkcí, manipulaci s řetězci, převody typů a vstupy/výstupy založené na souborech a konzole. Neobsahuje standardní sadu „ typů kontejnerů “, jako je C ++ Standard Template Library , natož kompletní sady nástrojů pro grafické uživatelské rozhraní (GUI), síťové nástroje a množství dalších funkcí, které standardně poskytuje Java a .NET Framework . Hlavní výhodou malé standardní knihovny je, že zajištění pracovního prostředí ISO C je mnohem snazší než u jiných jazyků, a proto je přenesení C na novou platformu poměrně snadné.

Viz také

Poznámky

Reference

Další čtení

externí odkazy