stringtranslate.com

Biblioteca estándar de C

La biblioteca estándar de C , a veces denominada libc , [ cita requerida ] es la biblioteca estándar para el lenguaje de programación C , como se especifica en el estándar ISO C. [1] A partir del estándar ANSI C original , se desarrolló al mismo tiempo que la especificación POSIX de la biblioteca C , que es un superconjunto de esta. [2] [3] Dado que ANSI C fue adoptado por la Organización Internacional de Normalización , [4] la biblioteca estándar de C también se denomina biblioteca ISO C. [ cita requerida ]

La biblioteca estándar de C proporciona macros , definiciones de tipos y funciones para tareas como manipulación de cadenas , cálculo matemático, procesamiento de entrada/salida, gestión de memoria y entrada/salida .

Interfaz de programación de aplicaciones (API)

Archivos de encabezado

La interfaz de programación de aplicaciones (API) de la biblioteca estándar de C se declara en una serie de archivos de encabezado . Cada archivo de encabezado contiene una o más declaraciones de funciones, definiciones de tipos de datos y macros.

Después de un largo período de estabilidad, se agregaron tres nuevos archivos de encabezado ( iso646.h, wchar.h, y ) con el Anexo Normativo 1 (NA1), una adición al Estándar C ratificado en 1995. Se agregaron seis archivos de encabezado más ( , , , , y ) con C99 , una revisión del Estándar C publicada en 1999, y cinco archivos más ( , , , y ) con C11 en 2011. En total, ahora hay 29 archivos de encabezado:wctype.hcomplex.hfenv.hinttypes.hstdbool.hstdint.htgmath.hstdalign.hstdatomic.hstdnoreturn.hthreads.huchar.h

Tres de los archivos de encabezado ( complex.h, stdatomic.h, y threads.h) son características condicionales que las implementaciones no están obligadas a soportar.

El estándar POSIX agregó varios encabezados C no estándar para funciones específicas de Unix. Muchos de ellos se han incorporado a otras arquitecturas. Algunos ejemplos son fcntl.hy unistd.h. Varios otros grupos están utilizando otros encabezados no estándar: la biblioteca C de GNU tiene alloca.hy OpenVMS tiene la va_count()función .

Documentación

En los sistemas tipo Unix, la documentación autorizada de la API se proporciona en forma de páginas de manual . En la mayoría de los sistemas, las páginas de manual sobre las funciones de la biblioteca estándar se encuentran en la sección 3; la sección 7 puede contener algunas páginas más genéricas sobre conceptos subyacentes (por ejemplo, man 7 math_erroren Linux ).

Implementaciones

Los sistemas tipo Unix suelen tener una biblioteca C en forma de biblioteca compartida , pero los archivos de encabezado (y la cadena de herramientas del compilador) pueden faltar en una instalación, por lo que el desarrollo en C puede no ser posible. La biblioteca C se considera parte del sistema operativo en sistemas tipo Unix; además de las funciones especificadas por el estándar C, incluye otras funciones que son parte de la API del sistema operativo, como las funciones especificadas en el estándar POSIX . Las funciones de la biblioteca C, incluidas las del estándar ISO C, son ampliamente utilizadas por los programas y se consideran no solo una implementación de algo en el lenguaje C, sino también parte de facto de la interfaz del sistema operativo. Los sistemas operativos tipo Unix generalmente no pueden funcionar si se borra la biblioteca C. Esto es cierto para las aplicaciones que están vinculadas dinámicamente en lugar de estáticamente. Además, el núcleo en sí (al menos en el caso de Linux) opera independientemente de cualquier biblioteca.

En Microsoft Windows, las bibliotecas dinámicas del sistema central ( DLL ) proporcionan una implementación de la biblioteca estándar de C para el compilador Microsoft Visual C++ v6.0; la biblioteca estándar de C para las versiones más nuevas del compilador Microsoft Visual C++ es proporcionada por cada compilador individualmente, así como por paquetes redistribuibles . Las aplicaciones compiladas escritas en C están enlazadas estáticamente con una biblioteca de C, o enlazadas a una versión dinámica de la biblioteca que se envía con estas aplicaciones, en lugar de depender de que estén presentes en los sistemas de destino. Las funciones en la biblioteca de C de un compilador no se consideran interfaces para Microsoft Windows.

Existen muchas implementaciones de bibliotecas C, que se incluyen con varios sistemas operativos y compiladores de C. Algunas de las implementaciones más populares son las siguientes:

Funciones integradas del compilador

Algunos compiladores (por ejemplo, GCC [7] ) proporcionan versiones integradas de muchas de las funciones de la biblioteca estándar de C; es decir, las implementaciones de las funciones se escriben en el archivo de objeto compilado y el programa llama a las versiones integradas en lugar de las funciones del archivo de objeto compartido de la biblioteca de C. Esto reduce la sobrecarga de llamadas a funciones, especialmente si las llamadas a funciones se reemplazan con variantes en línea , y permite otras formas de optimización (ya que el compilador conoce las características de flujo de control de las variantes integradas), pero puede causar confusión durante la depuración (por ejemplo, las versiones integradas no se pueden reemplazar con variantes instrumentadas ).

Sin embargo, las funciones incorporadas deben comportarse como funciones ordinarias de acuerdo con ISO C. La implicación principal es que el programa debe ser capaz de crear un puntero a estas funciones tomando su dirección e invocar la función por medio de ese puntero. Si dos punteros a la misma función se derivan en dos unidades de traducción diferentes en el programa, estos dos punteros deben compararse como iguales; es decir, la dirección se obtiene al resolver el nombre de la función, que tiene un enlace externo (a nivel de programa).

Enlace, libm

En FreeBSD [8] y glibc, [9] algunas funciones como sin() no están enlazadas de forma predeterminada y, en su lugar, se incluyen en la biblioteca matemática libm . Si se utiliza alguna de ellas, se debe proporcionar al enlazador la directiva -lm. POSIX requiere que el compilador c99 admita -lm, y que las funciones declaradas en los encabezados math.h, complex.h, y fenv.hestén disponibles para enlazar si -lmse especifica , pero no especifica si las funciones están enlazadas de forma predeterminada. [10] musl satisface este requisito al poner todo en una única biblioteca libc y proporcionar una libm vacía. [11]

Detección

Según el estándar C, la macro __STDC_HOSTED__se debe definir como 1 si la implementación está alojada. Una implementación alojada tiene todos los encabezados especificados por el estándar C. Una implementación también puede ser independiente , lo que significa que estos encabezados no estarán presentes. Si una implementación es independiente , se debe definir __STDC_HOSTED__como 0 .

Problemas y soluciones alternativas

Vulnerabilidades de desbordamiento de búfer

Algunas funciones de la biblioteca estándar de C son conocidas por tener vulnerabilidades de desbordamiento de búfer y, en general, por fomentar una programación llena de errores desde su adopción. [a] Los elementos más criticados son:

Excepto en el caso extremo de gets(), todas las vulnerabilidades de seguridad se pueden evitar introduciendo código auxiliar para realizar la gestión de memoria, comprobación de límites, comprobación de entrada, etc. Esto se suele hacer en forma de envoltorios que hacen que las funciones de la biblioteca estándar sean más seguras y fáciles de usar. Esto se remonta al libro The Practice of Programming de B. Kernighan y R. Pike, donde los autores suelen utilizar envoltorios que imprimen mensajes de error y abandonan el programa si se produce un error.

El comité ISO C publicó los informes técnicos TR 24731-1 [12] y está trabajando en el TR 24731-2 [13] para proponer la adopción de algunas funciones con verificación de límites y asignación automática de búfer, respectivamente. El primero recibió severas críticas y algunos elogios [14] [15] , mientras que el segundo tuvo una respuesta mixta.

A pesar de las preocupaciones, TR 24731-1 se integró en la ruta de estándares C en ISO/IEC 9899:2011 (C11), Anexo K ( Interfaces de verificación de límites ), y se implementó aproximadamente en la biblioteca de tiempo de ejecución C/++ (CRT) de Microsoft para las plataformas Win32 y Win64.

(De manera predeterminada, los compiladores C y C++ de Microsoft Visual Studio emiten advertencias cuando se utilizan funciones antiguas e "inseguras". Sin embargo, la implementación de Microsoft de TR 24731-1 es sutilmente incompatible tanto con TR 24731-1 como con Annex K, [16] por lo que es común que los proyectos portables deshabiliten o ignoren estas advertencias. Se pueden deshabilitar directamente emitiendo

#pragma advertencia(deshabilitar: 4996)

antes/alrededor del sitio de llamada en cuestión, o indirectamente mediante la emisión

#define _CRT_SECURE_SIN_ADVERTENCIAS 1

antes de incluir cualquier encabezado. [17] La ​​opción de línea de comandos /D_CRT_NO_SECURE_WARNINGS=1debería tener el mismo efecto que esta #define.)

Problemas de subprocesamiento, vulnerabilidad a las condiciones de carrera

La strerror()rutina es criticada por no ser segura para los subprocesos y por ser vulnerable a las condiciones de carrera .

Manejo de errores

El manejo de errores de las funciones en la biblioteca estándar de C no es consistente y a veces resulta confuso. Según la página del manual de Linux math_error, "La situación actual (versión 2.8) bajo glibc es confusa. La mayoría de las funciones (pero no todas) generan excepciones en caso de errores. Algunas también establecen errno . Unas pocas funciones establecen errno , pero no generan una excepción. Unas pocas funciones no hacen ninguna de las dos cosas". [18]

Normalización

El lenguaje C original no proporcionaba funciones integradas como operaciones de E/S, a diferencia de los lenguajes tradicionales como COBOL y Fortran . [ cita requerida ] Con el tiempo, las comunidades de usuarios de C compartieron ideas e implementaciones de lo que ahora se denomina bibliotecas estándar de C. Muchas de estas ideas se incorporaron eventualmente a la definición del lenguaje C estandarizado.

Tanto Unix como C fueron creados en los Laboratorios Bell de AT&T a finales de los años 60 y principios de los 70. Durante los años 70, el lenguaje C se hizo cada vez más popular. Muchas universidades y organizaciones comenzaron a crear sus propias variantes del lenguaje para sus propios proyectos. A principios de los años 80, los problemas de compatibilidad entre las diversas implementaciones de C se hicieron evidentes. En 1983, el Instituto Nacional Estadounidense de Estándares (ANSI) formó un comité para establecer una especificación estándar de C conocida como " ANSI C ". Este trabajo culminó en la creación del llamado estándar C89 en 1989. Parte del estándar resultante fue un conjunto de bibliotecas de software llamado biblioteca estándar ANSI C.

Biblioteca estándar POSIX

POSIX , así como SUS , especifican una serie de rutinas que deberían estar disponibles además de las de la biblioteca estándar básica de C. La especificación POSIX incluye archivos de encabezado para, entre otros usos, multi-threading , networking y expresiones regulares . Estos se implementan a menudo junto con la funcionalidad de la biblioteca estándar de C, con distintos grados de proximidad. Por ejemplo, glibc implementa funciones como forkwithin libc.so, pero antes de que NPTL se fusionara con glibc, constituía una biblioteca separada con su propio argumento de indicador de enlazador. A menudo, esta funcionalidad especificada por POSIX se considerará parte de la biblioteca; la biblioteca básica de C puede identificarse como la biblioteca ANSI o ISO de C.

Biblioteca BSD

BSD libc es un superconjunto de la biblioteca estándar POSIX compatible con las bibliotecas C incluidas en los sistemas operativos BSD, como FreeBSD , NetBSD , OpenBSD y macOS . BSD libc tiene algunas extensiones que no están definidas en el estándar original, muchas de las cuales aparecieron por primera vez en la versión 4.4BSD de 1994 (la primera que se desarrolló en gran medida después de que se publicara el primer estándar en 1989). Algunas de las extensiones de BSD libc son:

La biblioteca estándar de C en otros lenguajes

Algunos lenguajes incluyen la funcionalidad de la biblioteca estándar de C en sus propias bibliotecas. La biblioteca puede adaptarse para que se ajuste mejor a la estructura del lenguaje, pero la semántica operativa se mantiene similar.

C++

El lenguaje C++ incorpora la mayoría de las construcciones de la biblioteca estándar de C, excluyendo la maquinaria específica de C. Las funciones de la biblioteca estándar de C se exportan desde la biblioteca estándar de C++ de dos maneras.

Para compatibilidad con versiones anteriores y cruzadas de C y C++ anterior al estándar, se puede acceder a las funciones en el espacio de nombres global ( : :), después de incluir el nombre del encabezado estándar de C como en C. [40] Por lo tanto, el programa C++98#include

#include <stdio.h> int main () { return :: puts ( "¡Hola, mundo!" ) == EOF ; }      

Debería mostrar un comportamiento (aparentemente) idéntico al programa C95

#include <stdio.h> int main ( void ) { return puts ( "¡Hola, mundo!" ) == EOF ; }      

A partir de C++98 , las funciones de C también están disponibles en el espacio de nombres ::std (por ejemplo, C  printf como C++  ::std::printf , atoi como ::std::atoi , feof como ::std::feof ), al incluir header en lugar del header de C correspondiente . Por ejemplo, <cstdio> sustituye a <stdio.h> y <cmath> a <math.h> ; observe la falta de la extensión .h en los nombres de encabezado de C++.<chdrname><hdrname.h>

Por lo tanto, un programa C++≥98 equivalente (generalmente preferible) a los dos anteriores es:

#include <cstdio> int main () { return std :: puts ( "Hola, mundo" ) == EOF ; }      

Se puede emitir una declaración arriba o dentro de main para aplicar el prefijo ::std:: automáticamente, aunque generalmente se considera una mala práctica usarlo globalmente en los encabezados porque contamina el espacio de nombres global. [41]using namespace ::std

Faltan algunas de las versiones C++≥98 de los encabezados de C; por ejemplo, C≥11 <stdnoreturn.h> y <threads.h> no tienen contrapartes C++. [42]

Otros se reducen a marcadores de posición, como (hasta C++20 ) <ciso646> para C95 <iso646.h> , todas cuyas macros necesarias se representan como palabras clave en C++98. Las construcciones sintácticas específicas de C generalmente no son compatibles, incluso si su encabezado lo es. [43]

Existen varios encabezados C principalmente para compatibilidad con C++, y estos tienden a estar casi vacíos en C++. Por ejemplo, C99 – 17 <stdbool.h> requiere solo

#define bool _Bool #define falso 0 #define verdadero 1 #define __bool_true_false_are_defined 1

para simular soporte para las palabras claves bool , false y true de C++98 en C. C++11 requiere <stdbool.h> y <cstdbool> para compatibilidad, pero todo lo que necesitan definir es __bool_true_false_are_defined . C23 deja obsoleta la antigua palabra clave _Bool a favor de las nuevas palabras clave bool , false y true equivalentes a C++98 , por lo que los encabezados <stdbool.h> / <cstdbool> de C≥23 y C++≥11 son completamente equivalentes. (En particular, C23 no requiere ninguna macro __STDC_VERSION_BOOL_H__ para <stdbool.h> ).

Se prefiere el acceso a las funciones de la biblioteca C a través del espacio de nombres ::std y los nombres de encabezado de C++≥98 siempre que sea posible. Para fomentar la adopción, C++98 deja obsoletos los nombres de encabezado de C ( *.h ), por lo que es posible que el uso de encabezados de compatibilidad de C haga que un preprocesador de C++98–20 especialmente estricto genere un diagnóstico de algún tipo. Sin embargo, C++23 (inusualmente) deja obsoletos estos encabezados, por lo que las implementaciones/modos de C++ más nuevos no deberían quejarse sin que se les pida específicamente que lo hagan. [44]


Otros lenguajes adoptan un enfoque similar, colocando las funciones/rutinas de compatibilidad de C bajo un espacio de nombres común; estos incluyen D , Perl y Ruby .


Pitón

CPython incluye envoltorios para algunas de las funciones de la biblioteca C en su propia biblioteca común, y también otorga acceso más directo a las funciones y variables C a través de su paquete ctypes . [45]

De manera más general, Python  2. x especifica que los objetos de archivo integrados se “implementan utilizando el paquete stdio de C [46] ”, y se hace referencia frecuente a los comportamientos de la biblioteca estándar de C; se espera que las operaciones disponibles ( open, read, write, etc.) tengan el mismo comportamiento que las funciones C correspondientes ( fopen, fread, fwrite, etc.).

Sin embargo, la especificación de Python 3 depende considerablemente menos de los detalles específicos de C que Python 2 .

Óxido

Rust ofrece el paquete libc , que permite utilizar varias funciones de biblioteca y definiciones de tipos estándar de C (y otras). [47]

Comparación con bibliotecas estándar de otros lenguajes

La biblioteca estándar de C es pequeña en comparación con las bibliotecas estándar de otros lenguajes. La biblioteca de C proporciona un conjunto básico de funciones matemáticas, manipulación de cadenas, conversión de tipos y E/S basada en archivos y consola. No incluye un conjunto estándar de " tipos de contenedor " como la biblioteca de plantillas estándar de C++ , y mucho menos los kits de herramientas de interfaz gráfica de usuario (GUI) completos, las herramientas de red y la profusión de otras funciones que Java y .NET Framework proporcionan como estándar. La principal ventaja de la pequeña biblioteca estándar es que proporcionar un entorno C ISO funcional es mucho más fácil que con otros lenguajes y, en consecuencia, portar C a una nueva plataforma es comparativamente fácil.

Véase también

Notas

  1. ^ El gusano Morris , que se aprovecha de la conocida vulnerabilidad de este sistema, gets()fue creado ya en 1988.
  2. ^ En la biblioteca estándar de C, el cálculo de la longitud de la cadena y la búsqueda del final de una cadena tienen complejidades de tiempo lineal y son ineficientes cuando se usan en la misma cadena o en cadenas relacionadas repetidamente.

Referencias

  1. ^ ISO / IEC (2018). ISO/IEC 9899:2018(E): Lenguajes de programación - C §7
  2. ^ "La biblioteca C de GNU: introducción". gnu.org . Consultado el 5 de diciembre de 2013 .
  3. ^ "Diferencia entre la biblioteca estándar de C y la biblioteca POSIX de C". stackoverflow.com . 2012 . Consultado el 4 de marzo de 2015 .
  4. ^ "Estándares C". C: Estándares C . Keil . Consultado el 24 de noviembre de 2011 .
  5. ^ "Re: ¿Newlib admite CPU sin MMU?". Cygwin.com. 23 de marzo de 2006. Archivado desde el original el 22 de noviembre de 2008. Consultado el 28 de octubre de 2011 .
  6. ^ "musl libc". Etalabs.net . Consultado el 28 de octubre de 2011 .
  7. ^ Otras funciones integradas proporcionadas por GCC, Manual de GCC
  8. ^ "Compilación con cc" . Consultado el 2 de marzo de 2013 .
  9. ^ Weimer, Florian. "c - ¿Para qué funciones está destinado libm?". Desbordamiento de pila . Consultado el 24 de febrero de 2021 .
  10. ^ "c99 - compilar programas estándar en C". The Open Group Base Specification Issue 7, edición de 2018 . The Open Group . Consultado el 24 de febrero de 2021 .
  11. ^ "Preguntas frecuentes sobre musl". www.musl-libc.org . Consultado el 24 de febrero de 2021 .
  12. ^ "ISO/IEC TR 24731-1: Extensiones a la biblioteca C, Parte I: Interfaces de comprobación de límites" (PDF) . open-std.org. 2007-03-28 . Consultado el 2014-03-13 .
  13. ^ "ISO/IEC WDTR 24731-2: Extensiones a la biblioteca C, Parte II: Funciones de asignación dinámica" (PDF) . open-std.org. 2008-08-10 . Consultado el 2014-03-13 .
  14. ^ ¿Utiliza las funciones 'seguras' TR 24731 en su código C? - Desbordamiento de pila
  15. ^ "Revisión del Grupo Austin de la norma ISO/IEC WDTR 24731" . Consultado el 28 de octubre de 2011 .
  16. ^ "Experiencia de campo con el Anexo K: interfaces de verificación de límites" . Consultado el 9 de octubre de 2024 .
  17. ^ "Características de seguridad en el CRT: eliminación de las advertencias de desuso" . Consultado el 9 de octubre de 2024 .
  18. ^ "math_error - detección de errores en funciones matemáticas". man7.org . 2008-08-11 . Consultado el 2014-03-13 .
  19. ^ "árbol". Man.freebsd.org . 2007-12-27 . Consultado el 2013-08-25 .
  20. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/sys/sys/tree.h". bxr.su .
  21. ^ "cola". Man.freebsd.org . 2011-05-13 . Consultado el 2013-08-25 .
  22. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/sys/sys/queue.h". bxr.su .
  23. ^ "fgetln". Man.freebsd.org . 19 de abril de 1994 . Consultado el 25 de agosto de 2013 .
  24. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/lib/libc/stdio/fgetln.c". bxr.su .
  25. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/include/stdio.h". bxr.su .
  26. ^ "fts". Man.freebsd.org . 2012-03-18 . Consultado el 2013-08-25 .
  27. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/include/fts.h". bxr.su .
  28. ^ "db". Man.freebsd.org . 10 de septiembre de 2010 . Consultado el 25 de agosto de 2013 .
  29. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/include/db.h". bxr.su .
  30. ^ Miller, Todd C. y Theo de Raadt. strlcpy y strlcat: copia y concatenación de cadenas segura y consistente. Actas de la Conferencia técnica anual de USENIX de 1999, 6 al 11 de junio de 1999, págs. 175 a 178.
  31. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/lib/libc/string/strlcat.c". bxr.su .
  32. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/lib/libc/string/strlcpy.c". bxr.su .
  33. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/lib/libc/string/strncat.c". bxr.su .
  34. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/lib/libc/string/strncpy.c". bxr.su .
  35. ^ "err". Man.freebsd.org . 2012-03-29 . Consultado el 2013-08-25 .
  36. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/include/err.h". bxr.su .
  37. ^ "vis(3)". Man.FreeBSD.org . Consultado el 14 de septiembre de 2013 .
  38. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/lib/libc/gen/vis.c". bxr.su .
  39. ^ "Referencia cruzada BSD del superusuario: /OpenBSD/include/vis.h". bxr.su .
  40. ^ Encabezados de la biblioteca estándar de C++: encabezados de compatibilidad con C , consultado el 9 de octubre de 2024
  41. ^ Kieras, David (15 de febrero de 2015). "Uso de "using": Cómo usar el espacio de nombres std" (PDF) . Documentos de EECS381 . Departamento de EECS, Universidad de Michigan. Archivado (PDF) del original el 24 de diciembre de 2022 . Consultado el 9 de octubre de 2024 . Una sola declaración en un solo archivo de encabezado en un proyecto complejo puede arruinar la administración del espacio de nombres para todo el proyecto. Por lo tanto, ¡no se permiten declaraciones [ ] de nivel superior en un archivo de encabezado!using namespace std;using namespace
  42. ^ "Encabezados de la biblioteca estándar de C++: encabezados de C no admitidos" . Consultado el 9 de octubre de 2024 .
  43. ^ "Encabezados de la biblioteca estándar de C++: encabezados de C sin sentido" . Consultado el 9 de octubre de 2024 .
  44. ^ "Encabezados de la biblioteca estándar de C++: encabezados de compatibilidad con C" . Consultado el 9 de octubre de 2024 .
  45. ^ "ctypes: una biblioteca de funciones externas para Python". docs.python.com . Consultado el 9 de octubre de 2024 .
  46. ^ "La biblioteca estándar de Python, §5.9: Objetos de archivo" . Consultado el 9 de octubre de 2024 . Los objetos de archivo se implementan utilizando el paquete stdio de C y se pueden crear con la función incorporada .open()
  47. ^ "Crate libc". Rust Crates . Consultado el 9 de octubre de 2024 .

Lectura adicional

Enlaces externos