Стандартная библиотека C
Стандартная библиотека C (libc) |
---|
Общие темы |
Разные заголовки |
|
Стандартная библиотека C или libc — это стандартная библиотека для языка программирования C , как указано в ISO C. стандарте [1] Начиная с исходного стандарта ANSI C , он был разработан одновременно со спецификацией POSIX библиотеки C , которая является ее расширенной версией. [2] [3] Поскольку ANSI C был принят Международной организацией по стандартизации , [4] Стандартную библиотеку C также называют библиотекой ISO C.
Стандартная библиотека C предоставляет макросы , определения типов и функции для таких задач, как обработка строк , математические вычисления, обработка ввода/вывода, управление памятью и ряд других операционной системы служб .
Интерфейс прикладного программирования (API)
[ редактировать ]Заголовочные файлы
[ редактировать ]Интерфейс прикладного программирования (API) стандартной библиотеки C объявлен в ряде заголовочных файлов . Каждый файл заголовка содержит одно или несколько объявлений функций, определений типов данных и макросов.
После длительного периода стабильности появились три новых заголовочных файла ( iso646.h
, wchar.h
, и wctype.h
) были добавлены Нормативным дополнением 1 (NA1), дополнением к стандарту C, ратифицированному в 1995 году. Еще шесть файлов заголовков ( complex.h
, fenv.h
, inttypes.h
, stdbool.h
, stdint.h
, и tgmath.h
) были добавлены вместе с C99 , версией стандарта C, опубликованной в 1999 году, и еще пятью файлами ( stdalign.h
, stdatomic.h
, stdnoreturn.h
, threads.h
, и uchar.h
) с C11 в 2011 году. Всего теперь существует 29 заголовочных файлов:
Имя | От | Описание |
---|---|---|
<assert.h> | Объявляет макрос Assert , используемый для обнаружения логических ошибок и других типов ошибок при отладке программы. | |
<complex.h> | С99 | Определяет набор функций для работы с комплексными числами . |
<ctype.h> | Определяет набор функций, используемых для классификации символов по их типам или для преобразования верхнего и нижнего регистра способом, независимым от используемого набора символов (обычно ASCII или одно из его расширений, хотя реализации, использующие EBCDIC также известны ). | |
<errno.h> | Для тестирования кодов ошибок, сообщаемых библиотечными функциями. | |
<fenv.h> | С99 | Определяет набор функций для управления средой с плавающей запятой . |
<float.h> | Определяет макроконстанты, определяющие свойства библиотеки с плавающей запятой, зависящие от реализации . | |
<inttypes.h> | С99 | Определяет целочисленные типы точной ширины . |
<iso646.h> | NA1 | Определяет несколько макросов , которые реализуют альтернативные способы выражения нескольких стандартных токенов. Для программирования в различных наборах символов ISO 646 . |
<limits.h> | Определяет макроконстанты, задающие свойства целочисленных типов, зависящие от реализации. | |
<locale.h> | Определяет функции локализации . | |
<math.h> | Определяет общие математические функции . | |
<setjmp.h> | Объявляет макросы setjmp и longjmp , которые используются для нелокальных выходов. | |
<signal.h> | Определяет функции обработки сигналов . | |
<stdalign.h> | С11 | Для запроса и указания выравнивания объектов. |
<stdarg.h> | Для доступа к различному количеству аргументов, передаваемых функциям. | |
<stdatomic.h> | С11 | Для атомарных операций с данными, совместно используемыми между потоками. |
<stdbool.h> | С99 | Определяет логический тип данных . |
<stddef.h> | Определяет несколько полезных типов и макросов . | |
<stdint.h> | С99 | Определяет целочисленные типы точной ширины . |
<stdio.h> | Определяет основные функции ввода и вывода. | |
<stdlib.h> | Определяет функции числового преобразования , функции генерации псевдослучайных чисел , распределение памяти , функции управления процессом. | |
<stdnoreturn.h> | С11 | Для указания невозвратных функций |
<string.h> | Определяет функции обработки строк | |
<tgmath.h> | С99 | Определяет общие математические функции . |
<threads.h> | С11 | Определяет функции для управления несколькими потоками , мьютексами и условными переменными. |
<time.h> | Определяет функции обработки даты и времени. | |
<uchar.h> | С11 | Типы и функции для управления Юникода символами |
<wchar.h> | NA1 | Определяет функции обработки широких строк |
<wctype.h> | NA1 | Определяет набор функций, используемых для классификации широких символов по их типам или для преобразования верхнего и нижнего регистра. |
Три заголовочных файла ( complex.h
, stdatomic.h
, и threads.h
) — это условные функции, которые реализации не обязаны поддерживать.
В стандарт POSIX добавлено несколько нестандартных заголовков C для специфичных для Unix функций. Многие нашли свой путь к другим архитектурам. Примеры включают в себя fcntl.h
и unistd.h
. Ряд других групп используют другие нестандартные заголовки – в библиотеке GNU C есть alloca.h
и OpenVMS имеет va_count()
функция.
Документация
[ редактировать ]В Unix-подобных системах авторитетная документация API предоставляется в виде страниц руководства . В большинстве систем страницы руководства по функциям стандартной библиотеки находятся в разделе 3; раздел 7 может содержать несколько более общих страниц, посвященных основным концепциям (например, man 7 math_error
в Linux ).
Реализации
[ редактировать ]Unix-подобные системы обычно имеют библиотеку C в форме общей библиотеки , но файлы заголовков (и набор инструментов компилятора) могут отсутствовать в установке, поэтому разработка C может быть невозможна. Библиотека C считается частью операционной системы Unix-подобных систем; Помимо функций, определенных стандартом C, он включает в себя другие функции, являющиеся частью API операционной системы, например функции, указанные в стандарте POSIX . Функции библиотеки C, включая стандартные функции ISO C, широко используются программами и рассматриваются так, как если бы они были не только реализацией чего-то на языке C, но и де-факто частью интерфейса операционной системы. Unix-подобные операционные системы обычно не могут работать, если библиотека C удалена. Это справедливо для приложений, которые связаны динамически, а не статически. Далее само ядро (по крайней мере, в случае с Linux) работает независимо от каких-либо библиотек.
В Microsoft Windows основные системные динамические библиотеки ( DLL ) предоставляют реализацию стандартной библиотеки C для компилятора Microsoft Visual C++ v6.0; Стандартная библиотека C для более новых версий компилятора Microsoft Visual C++ предоставляется каждым компилятором индивидуально, а также распространяемыми пакетами. Скомпилированные приложения, написанные на C, либо статически связываются с библиотекой C, либо связываются с динамической версией библиотеки, которая поставляется с этими приложениями, а не предполагается, что они присутствуют в целевых системах. Функции в библиотеке C компилятора не рассматриваются как интерфейсы к Microsoft Windows.
Существует множество реализаций библиотеки C, поставляемых как с различными операционными системами, так и с компиляторами C. Вот некоторые из популярных реализаций:
- BSD libc , различные реализации, распространяемые с BSD. операционными системами, производными от
- Библиотека GNU C (glibc), используемая в GNU Hurd , GNU/kFreeBSD и Linux.
- Библиотека времени выполнения Microsoft C , часть Microsoft Visual C++ . Существует две версии библиотеки: MSVCRT, которая была распространяемой до версии 12/Visual Studio 2013 с низкой совместимостью с C99, и новая UCRT (Universal C Run Time), которая является частью Windows 10 и 11, поэтому всегда присутствует для ссылки. , а также совместим с C99 [1] .
- Dietlibc , альтернативная небольшая реализация стандартной библиотеки C (без MMU)
- μClibc , стандартная библиотека C для встроенных систем μClinux (без MMU)
- uclibc-ng , встроенная библиотека C, ответвление μClibc, все еще поддерживается, с модуля управления памятью (MMU). поддержкой
- Newlib — стандартная библиотека C для встраиваемых систем (без MMU). [5] и используется в дистрибутиве Cygwin GNU для Windows.
- klibc , в первую очередь для загрузки систем Linux.
- musl , еще одна облегченная реализация стандартной библиотеки C для систем Linux. [6]
- Bionic , первоначально разработанная Google для встроенной операционной системы Android, производная от BSD libc.
- picolibc , разработанный Кейтом Паккардом , предназначенный для небольших встраиваемых систем с ограниченным объемом оперативной памяти, основанный на коде Newlib и AVR Libc.
Встроенные функции компилятора
[ редактировать ]Некоторые компиляторы (например, GCC [7] ) предоставляют встроенные версии многих функций стандартной библиотеки C; то есть реализации функций записываются в скомпилированный объектный файл , и программа вызывает встроенные версии вместо функций из общего объектного файла библиотеки C. Это уменьшает накладные расходы на вызовы функций, особенно если вызовы функций заменяются встроенными вариантами, и допускает другие формы оптимизации (поскольку компилятор знает характеристики потока управления встроенных вариантов), но может вызвать путаницу при отладке (например, , встроенные версии не могут быть заменены инструментальными вариантами).
Однако встроенные функции должны вести себя как обычные функции в соответствии с ISO C. Основной смысл заключается в том, что программа должна иметь возможность создавать указатель на эти функции, взяв их адрес, и вызывать функцию с помощью этого указателя. Если два указателя на одну и ту же функцию получены в двух разных единицах перевода в программе, эти два указателя должны сравниваться равными; то есть адрес получается путем разрешения имени функции, которая имеет внешнюю (в масштабе всей программы) связь.
Связывание, libm
[ редактировать ]Под FreeBSD [8] и глибк, [9] некоторые функции, такие как sin(), не связаны по умолчанию и вместо этого включены в математическую библиотеку libm . Если какой-либо из них используется, компоновщику должна быть присвоена директива -lm
. POSIX требует, чтобы компилятор c99 поддерживал -lm
и что функции, объявленные в заголовках math.h
, complex.h
, и fenv.h
доступны для связывания, если -lm
указан, но не указывает, связаны ли функции по умолчанию. [10] musl удовлетворяет этому требованию, помещая все в одну библиотеку libc и предоставляя пустую библиотеку libm. [11]
Обнаружение
[ редактировать ]Согласно стандарту C макрос __STDC_HOSTED__
должно быть определено как 1, если реализация размещена. Размещенная реализация имеет все заголовки, определенные стандартом C. Реализация также может быть автономной , что означает отсутствие этих заголовков. Если реализация является автономной , она должна определять __STDC_HOSTED__
до 0 .
Проблемы и обходные пути
[ редактировать ]Уязвимости переполнения буфера
[ редактировать ]Некоторые функции стандартной библиотеки C известны своей уязвимостью к переполнению буфера и, как правило, способствуют программированию с ошибками с момента их принятия. [а] Наиболее критикуемые позиции:
- процедуры манипуляции со строками , в том числе
strcpy()
иstrcat()
, из-за отсутствия проверки границ и возможного переполнения буфера, если границы не проверяются вручную; - строковые подпрограммы в целом, для побочных эффектов , поощряющие безответственное использование буфера, не всегда гарантирующие действительный с нулевым завершением , вычисление линейной длины; вывод [б]
printf()
семейство подпрограмм, предназначенных для порчи стека выполнения , когда строка формата не соответствует заданным аргументам. Этот фундаментальный недостаток создал целый класс атак: атаки на форматную строку ;gets()
иscanf()
семейство процедур ввода-вывода из-за отсутствия (любой или простой) проверки длины входных данных.
За исключением крайнего случая с gets()
, всех уязвимостей безопасности можно избежать, введя вспомогательный код для управления памятью, проверки границ, проверки ввода и т. д. Это часто делается в виде оболочек, которые делают стандартные библиотечные функции более безопасными и простыми в использовании. Это восходит к книге Б. Кернигана и Р. Пайка «Практика программирования» , где авторы обычно используют оболочки, которые выводят сообщения об ошибках и завершают программу в случае возникновения ошибки.
Комитет ISO C опубликовал Технические отчеты TR 24731-1. [12] и работает по ТР 24731-2. [13] предложить принятие некоторых функций с проверкой границ и автоматическим выделением буфера соответственно. Первый встретил резкую критику с некоторой похвалой. [14] [15] последний получил неоднозначные ответы. Несмотря на это, TR 24731-1 был реализован в стандартной библиотеке Microsoft C, и его компилятор выдает предупреждения при использовании старых «небезопасных» функций.
Проблемы с потоками, уязвимость к условиям гонки
[ редактировать ]The strerror()
Подпрограмму критикуют за то, что она небезопасна для потоков и уязвима к условиям гонки .
Обработка ошибок
[ редактировать ]Обработка ошибок функций стандартной библиотеки C непоследовательна и иногда сбивает с толку. Согласно странице руководства Linux math_error
, «Текущая ситуация (версия 2.8) в glibc запутана. Большинство (но не все) функций вызывают исключения при ошибках. Некоторые также устанавливают errno . Несколько функций устанавливают errno , но не вызывают исключения. Очень немногие функции не делают ни того, ни другого. ." [16]
Стандартизация
[ редактировать ]Исходный язык C не содержал встроенных функций, таких как операции ввода-вывода, в отличие от традиционных языков, таких как COBOL и Fortran . [ нужна ссылка ] Со временем сообщества пользователей C поделились идеями и реализациями того, что сейчас называется стандартными библиотеками C. Многие из этих идей в конечном итоге были включены в определение стандартизированного языка C.
И Unix , и C были созданы в лабораториях Bell Laboratories компании AT&T в конце 1960-х — начале 1970-х годов. В 1970-е годы язык C становился все более популярным. Многие университеты и организации начали создавать собственные варианты языка для собственных проектов. К началу 1980-х годов стали очевидны проблемы совместимости между различными реализациями языка C. В 1983 году Американский национальный институт стандартов (ANSI) сформировал комитет для установления стандартной спецификации C, известной как « ANSI C ». Кульминацией этой работы стало создание в 1989 году так называемого стандарта C89. Частью полученного стандарта стал набор программных библиотек, названный стандартной библиотекой ANSI C.
Стандартная библиотека POSIX
[ редактировать ]POSIX , как и SUS , определяют ряд подпрограмм, которые должны быть доступны помимо тех, которые есть в базовой стандартной библиотеке C. Спецификация POSIX включает файлы заголовков, среди прочего, для многопоточности , работы в сети и регулярных выражений . Они часто реализуются вместе с функциональностью стандартной библиотеки C с разной степенью близости. Например, glibc реализует такие функции, как fork
в пределах libc.so
, но до того, как NPTL был объединен с glibc, он представлял собой отдельную библиотеку с собственным аргументом флага компоновщика. Часто эта функциональность, определенная POSIX, рассматривается как часть библиотеки; базовая библиотека C может быть идентифицирована как библиотека C ANSI или ISO .
БСД libc
[ редактировать ]BSD libc — это расширенная версия стандартной библиотеки POSIX, поддерживаемая библиотеками C, включенными в BSD, операционные системы такие как FreeBSD , NetBSD , OpenBSD и macOS . BSD libc имеет некоторые расширения, которые не определены в исходном стандарте, многие из которых впервые появились в версии 4.4BSD 1994 года (первая, которая получила широкое развитие после выхода первого стандарта в 1989 году). Вот некоторые расширения BSD libc:
sys/tree.h
– содержит реализацию красно-черного дерева и дерева расширения. [17] [18]sys/queue.h
— реализации связанного списка , очередей , хвостовой очереди и т. д. [19] [20]fgetln()
– определено вstdio.h
. Это можно использовать для чтения файла построчно. [21] [22] [23]fts.h
– содержит некоторые функции для обхода файловой иерархии [24] [25]db.h
— некоторые функции для подключения к Berkeley DB [26] [27]strlcat()
иstrlcpy()
– безопасные альтернативыstrncat()
иstrncpy()
[28] [29] [30] [31] [32]err.h
– содержит некоторые функции для печати форматированных сообщений об ошибках [33] [34]vis.h
– содержитvis()
функция. Эта функция используется для отображения непечатаемых символов в визуальном формате. [35] [36] [37]
Стандартная библиотека C на других языках
[ редактировать ]Некоторые языки включают функциональность стандартной библиотеки C в свои собственные библиотеки. Библиотеку можно адаптировать, чтобы она лучше соответствовала структуре языка, но операционная семантика остается неизменной. Например, язык C++ включает в себя функциональность стандартной библиотеки C в пространстве имен. std
(например, std::printf
, std::atoi
, std::feof
), в заголовочных файлах с именами, похожими на имена C ( cstdio
, cmath
, cstdlib
, и т. д.). Другими языками, в которых используются аналогичные подходы, являются D , Perl , Ruby и основная реализация Python, известная как CPython . Например, в Python 2 встроенные файловые объекты определяются как «реализованные с использованием языка C». stdio
упаковка", [38] поэтому ожидается, что доступные операции (открытие, чтение, запись и т. д.) будут вести себя так же, как и соответствующие функции C. У Руста есть ящик под названием libc , который позволяет использовать несколько функций C, структур и других определений типов. [39]
Сравнение со стандартными библиотеками других языков
[ редактировать ]Стандартная библиотека C мала по сравнению со стандартными библиотеками некоторых других языков. Библиотека C предоставляет базовый набор математических функций, манипуляций со строками, преобразований типов , а также файлового и консольного ввода-вывода. Он не включает стандартный набор « типов контейнеров », таких как C++ стандартная библиотека шаблонов , не говоря уже о полных наборах инструментов графического пользовательского интерфейса (GUI), сетевых инструментах и изобилии других функций, которые Java и .NET Framework предоставляют в стандартной комплектации. Основное преимущество небольшой стандартной библиотеки состоит в том, что обеспечить рабочую среду ISO C намного проще, чем с другими языками, и, следовательно, портировать C на новую платформу сравнительно легко.
См. также
[ редактировать ]Примечания
[ редактировать ]- ^ Червь Морриса , использующий известную уязвимость в
gets()
были созданы еще в 1988 году. - ^ в стандартной библиотеке C вычисление длины строки и поиск конца строки имеют линейные временные сложности и неэффективны при многократном использовании одних и тех же или связанных строк.
Ссылки
[ редактировать ]- ^ ИСО / МЭК (2018). ISO/IEC 9899:2018(E): Языки программирования – C §7
- ^ «Библиотека GNU C – Введение» . gnu.org . Проверено 5 декабря 2013 г.
- ^ «Разница между стандартной библиотекой C и библиотекой C POSIX» . stackoverflow.com . 2012 . Проверено 4 марта 2015 г.
- ^ «Стандарты Си» . C: Стандарты C. Кейл . Проверено 24 ноября 2011 г.
- ^ «Re: Поддерживает ли Newlib процессоры без mmu?» . Cygwin.com. 23 марта 2006 г. Архивировано из оригинала 22 ноября 2008 г. . Проверено 28 октября 2011 г.
- ^ "musl libc" . Эталабс.нет . Проверено 28 октября 2011 г.
- ^ Другие встроенные функции, предоставляемые GCC , Руководство GCC.
- ^ «Компиляция с помощью cc» . Проверено 2 марта 2013 г.
- ^ Веймер, Флориан. "c - Для каких функций предназначена libm?" . Переполнение стека . Проверено 24 февраля 2021 г.
- ^ «c99 — компилировать стандартные программы на языке C» . Базовые спецификации открытой группы, выпуск 7, издание 2018 г. Открытая группа . Проверено 24 февраля 2021 г.
- ^ "Часто задаваемые вопросы по музл" . www.musl-libc.org . Проверено 24 февраля 2021 г.
- ^ «ISO/IEC TR 24731-1: Расширения библиотеки C, Часть I: Интерфейсы проверки границ» (PDF) . open-std.org. 28 марта 2007 г. Проверено 13 марта 2014 г.
- ^ «ISO/IEC WDTR 24731-2: Расширения библиотеки C, Часть II: Функции динамического распределения» (PDF) . open-std.org. 10 августа 2008 г. Проверено 13 марта 2014 г.
- ^ Используете ли вы «безопасные» функции TR 24731 в своем коде на C? - Переполнение стека
- ^ «Обзор Austin Group ISO/IEC WDTR 24731» . Проверено 28 октября 2011 г.
- ^ «math_error — обнаружение ошибок математических функций» . man7.org . 11 августа 2008 г. Проверено 13 марта 2014 г.
- ^ "дерево" . Man.freebsd.org . 27 декабря 2007 г. Проверено 25 августа 2013 г.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/sys/sys/tree.h» . bxr.su.
- ^ "очередь" . Man.freebsd.org . 13 мая 2011 г. Проверено 25 августа 2013 г.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/sys/sys/queue.h» . bxr.su.
- ^ "фгетлн" . Man.freebsd.org . 19 апреля 1994 г. Проверено 25 августа 2013 г.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/lib/libc/stdio/fgetln.c» . bxr.su.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/include/stdio.h» . bxr.su.
- ^ "футы" . Man.freebsd.org . 18 марта 2012 г. Проверено 25 августа 2013 г.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/include/fts.h» . bxr.su.
- ^ "дб" . Man.freebsd.org . 10 сентября 2010 г. Проверено 25 августа 2013 г.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/include/db.h» . bxr.su.
- ^ Миллер, Тодд К. и Тео де Раадт. strlcpy и strlcat — согласованное, безопасное копирование и конкатенация строк . Материалы ежегодной технической конференции USENIX 1999 г., 6–11 июня 1999 г., стр. 175–178.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/lib/libc/string/strlcat.c» . bxr.su.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/lib/libc/string/strlcpy.c» . bxr.su.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/lib/libc/string/strncat.c» . bxr.su.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/lib/libc/string/strncpy.c» . bxr.su.
- ^ «ошибка» . Man.freebsd.org . 29 марта 2012 г. Проверено 25 августа 2013 г.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/include/err.h» . bxr.su.
- ^ "vis(3)" . Man.FreeBSD.org . Проверено 14 сентября 2013 г.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/lib/libc/gen/vis.c» . bxr.su.
- ^ «Перекрестная ссылка BSD суперпользователя: /OpenBSD/include/vis.h» . bxr.su.
- ^ «Стандартная библиотека Python: 6.9. Файловые объекты» . Docs.python.org . Проверено 28 октября 2011 г.
- ^ "либк" . Ржавые ящики . Архивировано из оригинала 18 августа 2016 года . Проверено 31 июля 2016 г.
Дальнейшее чтение
[ редактировать ]- Плаугер, П.Дж. (1992). Стандартная библиотека C (1-е изд.). Прентис Холл. ISBN 978-0131315099 .
Внешние ссылки
[ редактировать ]- Справочное руководство по библиотеке C
- Удобный список заголовков, в каком стандарте
- Microsoft Подпрограммы выполнения Universal C по категориям в MSDN
- NetBSD. Руководство по библиотекам C Архивировано 23 декабря 2015 г. на Wayback Machine и полный исходный код библиотеки C.
- Страницы руководства по оригинальным стандартным библиотекам C в Unix