utilizar matematicas libreria lenguaje funciones ejemplos como c compilation math.h

matematicas - math h c++ function



¿Por qué tienes que vincular la biblioteca de matemáticas en C? (9)

Si <stdlib.h> o <stdio.h> en un programa en C, no tengo que vincularlos al compilar, pero sí debo vincular a <math.h> , usando -lm con gcc, por ejemplo:

gcc test.c -o test -lm

¿Cuál es la razón para esto? ¿Por qué tengo que vincular explícitamente la biblioteca matemática pero no las otras bibliotecas?


Si pongo stdlib.h o stdio.h, no tengo que vincularlos, pero tengo que vincularlos cuando compilo:

stdlib.h , stdio.h son los archivos de encabezado. Los incluyes para tu conveniencia. Solo pronostican qué símbolos estarán disponibles si se vincula en la biblioteca adecuada. Las implementaciones están en los archivos de la biblioteca, allí es donde realmente viven las funciones.

Incluir math.h es solo el primer paso para obtener acceso a todas las funciones matemáticas.

Además, no tiene que vincularse con libm si no usa sus funciones, incluso si hace un #include <math.h> que es solo un paso informativo para el compilador sobre los símbolos.

stdlib.h , stdio.h refiere a las funciones disponibles en libc , las cuales siempre están vinculadas para que el usuario no tenga que hacerlo él mismo.


Como dijo efímero, la biblioteca C de libc está vinculada de forma predeterminada y esta biblioteca contiene las implementaciones de stdlib.h, stdio.h y varios otros archivos de encabezado estándar. Solo para agregarlo, de acuerdo con " Una Introducción a GCC ", el comando del enlazador para un programa básico de "Hola Mundo" en C es el siguiente:

ld -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/libgcc-lib /i686/3.3.1/crtbegin.o -L/usr/lib/gcc-lib/i686/3.3.1 hello.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i686/3.3.1/crtend.o /usr/lib/crtn.o

Observe la opción -lc en la tercera línea que vincula la biblioteca C.


Creo que es algo arbitrario. Debe dibujar una línea en algún lugar (qué bibliotecas son predeterminadas y cuáles deben especificarse).

Te da la oportunidad de reemplazarlo por uno diferente que tenga las mismas funciones, pero no creo que sea muy común hacerlo.

EDITAR: (de mis propios comentarios): Creo que gcc hace esto para mantener la compatibilidad hacia atrás con el cc original. Supongo que el motivo por el cual cc hace esto es debido al tiempo de compilación: cc fue escrito para máquinas con mucha menos potencia de la que tenemos ahora. Una gran cantidad de programas no tienen matemática de punto flotante y probablemente tomaron todas las bibliotecas que no se usaban comúnmente por defecto. Supongo que el tiempo de compilación del sistema operativo UNIX y las herramientas que lo acompañan fueron la fuerza motriz.


Hay una discusión exhaustiva sobre la vinculación a bibliotecas externas en Introducción a GCC: vinculación con bibliotecas externas . Si una biblioteca es miembro de las bibliotecas estándar (como stdio), entonces no necesita especificar el compilador (realmente el enlazador) para vincularlas.

EDITAR: Después de leer algunas de las otras respuestas y comentarios, creo que la referencia libc.a y la referencia libm que vincula a ambas tienen mucho que decir acerca de por qué las dos están separadas.

Tenga en cuenta que muchas de las funciones en ''libm.a'' (la biblioteca matemática) están definidas en ''math.h'' pero no están presentes en libc.a. Algunas son, lo que puede resultar confuso, pero la regla general es esta: la biblioteca C contiene las funciones que debe dictar el ANSI, por lo que no necesita la -lm si solo utiliza las funciones del ANSI. En contraste, `libm.a ''contiene más funciones y es compatible con funcionalidades adicionales, como la devolución de llamadas matherr y el cumplimiento de varios estándares alternativos de comportamiento en caso de errores de PF. Vea la sección libm, para más detalles.


Las funciones en stdlib.h y stdio.h tienen implementaciones en libc.so (o libc.a para la vinculación estática), que está vinculada a su ejecutable por defecto (como si se especificara -lc ). Se puede indicar a GCC que evite este enlace automático con las opciones -nostdlib o -nodefaultlibs .

Las funciones matemáticas en math.h tienen implementaciones en libm.so (o libm.a para enlaces estáticos), y libm no está enlazado de forma predeterminada. Hay razones históricas para esta libm / libc , ninguna de ellas muy convincente.

Curiosamente, el tiempo de ejecución de C ++ libstdc++ requiere libm , por lo que si compila un programa de C ++ con GCC ( g++ ), automáticamente se vinculará a libm .


Recuerde que C es un lenguaje antiguo y que las FPU son un fenómeno relativamente reciente. La primera vez que vi C en procesadores de 8 bits fue un gran esfuerzo para hacer incluso aritmética de enteros de 32 bits. ¡Muchas de estas implementaciones ni siquiera tienen una biblioteca matemática de punto flotante disponible!

Incluso en las primeras 68000 máquinas (Mac, Atari ST, Amiga), los coprocesadores de punto flotante eran a menudo costosos complementos.

Para hacer todas esas matemáticas de punto flotante, necesitabas una biblioteca bastante grande. Y la matemática iba a ser lenta. Así que rara vez usaste flotadores. Intentaste hacer todo con enteros o enteros escalados. Cuando tenías que incluir math.h, apretabas los dientes. A menudo, escribirías tus propias aproximaciones y tablas de búsqueda para evitarlo.

Las compensaciones existieron durante mucho tiempo. A veces había paquetes matemáticos de la competencia llamados "fastmath" o similares. ¿Cuál es la mejor solución para las matemáticas? ¿Cosas realmente precisas pero lentas? ¿Inexacto pero rápido? ¿Grandes tablas para funciones trigonométricas? No fue hasta que los coprocesadores tenían la garantía de estar en la computadora que la mayoría de las implementaciones se hicieron obvias. Me imagino que hay algún programador en algún lugar ahora mismo, trabajando en un chip integrado, tratando de decidir si traer la biblioteca de matemáticas para manejar algún problema de matemáticas.

Es por eso que las matemáticas no eran estándar . Muchos o tal vez la mayoría de los programas no utilizaron un solo flotador. Si las FPU siempre hubieran existido y las flotillas y los dobles siempre fueran baratos para operar, sin duda habría habido una "amenaza".


stdio es parte de la biblioteca estándar de C con la que, de forma predeterminada, gcc enlazará.

Las implementaciones de la función matemática están en un archivo libm separado que no está vinculado de forma predeterminada, por lo que debe especificarlo -lm. Por cierto, no hay ninguna relación entre esos archivos de encabezado y los archivos de biblioteca.


here se da una explicación:

Entonces, si su programa usa funciones matemáticas e incluye math.h , entonces necesita vincular explícitamente la biblioteca matemática al pasar la -lm . La razón de esta separación en particular es que los matemáticos son muy exigentes con la forma en que se calculan sus matemáticas y pueden querer usar su propia implementación de las funciones matemáticas en lugar de la implementación estándar. Si las funciones matemáticas se libc.a en libc.a , no sería posible hacerlo.

[Editar]

Aunque no estoy seguro de estar de acuerdo con esto. Si tiene una biblioteca que proporciona, digamos, sqrt() , y la pasa antes que la biblioteca estándar, un enlazador de Unix tomará su versión, ¿verdad?


Supongo que es una forma de hacer que las aplicaciones que no las usan funcionen un poco mejor. Aquí está mi pensamiento sobre esto.

Los sistemas operativos x86 (y me imagino que otros) necesitan almacenar el estado de FPU en el cambio de contexto. Sin embargo, la mayoría de los sistemas operativos solo se molestan en guardar / restaurar este estado después de que la aplicación intente usar la FPU por primera vez.

Además de esto, es probable que haya un código básico en la biblioteca matemática que establecerá la FPU en un estado base sano cuando se cargue la biblioteca.

Por lo tanto, si no vincula ningún código matemático, nada de esto sucederá, por lo que el sistema operativo no tiene que guardar / restaurar ningún estado de FPU, lo que hace que los cambios de contexto sean un poco más eficientes.

Aunque solo una conjetura.

EDITAR: en respuesta a algunos de los comentarios, la misma premisa básica aún se aplica a los casos que no son de FPU (la premisa es que las aplicaciones que no hicieron uso de libm funcionan ligeramente mejor).

Por ejemplo, si hay una FPU suave que fue similar a la de los primeros días de C. Luego, tener libm separado podría evitar que muchos códigos grandes (y lentos si se usaron) se vincularan innecesariamente.

Además, si solo hay disponible un enlace estático, entonces se aplica un argumento similar que mantendría los tamaños ejecutables y los tiempos de compilación hacia abajo.