
No
si incluyo <stdlib.h>
o <stdio.h>
en un programa C no tengo que vincularlos al compilar, pero sí tengo que vincularlos a <math.h>
utilizando -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 de matemáticas pero no las otras bibliotecas?

Nosredna
Recuerde que C es un lenguaje antiguo y que las FPU son un fenómeno relativamente reciente. Primero vi C en procesadores de 8 bits donde era mucho trabajo hacer aritmética de enteros de 32 bits. Muchas de estas implementaciones ni siquiera tener ¡una biblioteca matemática de punto flotante disponible!
Incluso en las primeras máquinas 68000 (Mac, Atari ST, Amiga), los coprocesadores de punto flotante a menudo eran complementos costosos.
Para hacer todas esas matemáticas de punto flotante, necesitabas una biblioteca bastante grande. Y las matemáticas iban a ser lentas. Entonces rara vez usaste flotadores. Intentaste hacer todo con números enteros o números enteros escalados. Cuando tuviste que incluir math.h, apretaste los dientes. A menudo, escribiría sus 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? ¿Impreciso pero rápido? ¿Tablas grandes para funciones trigonométricas? No fue hasta que se garantizó que los coprocesadores estuvieran 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 incorporar la biblioteca matemática para manejar algún problema matemático.
Por eso las matemáticas no eran estándar. Muchos o tal vez la mayoría de los programas no usaban un solo flotador. Si las FPU siempre hubieran existido y los flotadores y los dobles siempre hubieran sido baratos para operar, sin duda habría habido un “stdmath”.

R.. GitHub DEJAR DE AYUDAR A ICE
Por ridícula práctica histórica que nadie está dispuesto a arreglar. La consolidación de todas las funciones requeridas por C y POSIX en un solo archivo de biblioteca no solo evitaría que esta pregunta se hiciera una y otra vez, sino que también ahorraría una cantidad significativa de tiempo y memoria al vincular dinámicamente, ya que cada .so
El archivo vinculado requiere las operaciones del sistema de archivos para ubicarlo y encontrarlo, y algunas páginas para sus variables estáticas, reubicaciones, etc.
Una implementación donde todas las funciones están en una biblioteca y el -lm
, -lpthread
, -lrt
etc. las opciones son todas no-ops (o enlace para vaciar .a
archivos) es perfectamente compatible con POSIX y ciertamente preferible.
Nota: estoy hablando de POSIX porque C en sí mismo no especifica nada sobre cómo se invoca el compilador. Por lo tanto, solo puede tratar gcc -std=c99 -lm
como la forma específica de implementación en la que se debe invocar al compilador para un comportamiento conforme.

efímero
Las funciones en stdlib.h
y stdio.h
tener implementaciones en libc.so
(o libc.a
para la vinculación estática), que está vinculado a su ejecutable de forma predeterminada (como si -lc
fueron especificados). GCC puede ser instruido para evitar este enlace automático con el -nostdlib
o -nodefaultlibs
opciones
Las funciones matemáticas en math.h
tener implementaciones en libm.so
(o libm.a
para enlaces estáticos), y libm
no está vinculado de forma predeterminada. Hay razones históricas para esto. libm
/libc
split, ninguno de ellos muy convincente.
Curiosamente, el tiempo de ejecución de C++ libstdc++
requiere libm
por lo que si compila un programa C++ con GCC (g++
), obtendrá automáticamente libm
vinculado en
es un error No debería tener que especificar explícitamente -lm
ya no. Quizás si suficientes personas se quejan de eso, se arreglará. (No creo seriamente en esto, ya que los mantenedores que están perpetuando la distinción son evidentemente muy terco, pero puedo esperar.)

Saptarshi das
A todas las bibliotecas les gusta stdio.h
y stdlib.h
tener su implementación en libc.so
o libc.a
y ser vinculado por el enlazador de forma predeterminada. las bibliotecas para libc.so
se vinculan automáticamente durante la compilación y se incluyen en el archivo ejecutable.
Pero math.h
tiene sus implementaciones en libm.so
o libm.a
que está separado de libc.so
y no se vincula de forma predeterminada y debe vincularlo manualmente mientras compila su programa en gcc
mediante el uso -lm
bandera.
El equipo gnu gcc lo diseñó para estar separado de los otros archivos de encabezado, mientras que los otros archivos de encabezado se vinculan de manera predeterminada, pero el archivo math.h no.
Aquí lea el punto 14.3, puede leerlo todo si lo desea:
Razón por la cual es necesario vincular math.h
Mira este artículo: ¿Por qué tenemos que vincular math.h en gcc?
Echa un vistazo al uso:
usando la biblioteca
Tenga en cuenta que -lm
Es posible que no siempre sea necesario especificarlo, incluso si usa algunas funciones matemáticas de C.
Por ejemplo, el siguiente programa simple:
#include <stdio.h>
#include <math.h>
int main() {
printf("output: %f\n", sqrt(2.0));
return 0;
}
se puede compilar y ejecutar correctamente con el siguiente comando:
gcc test.c -o test
Probado en gcc 7.5.0 (en Ubuntu 16.04) y gcc 4.8.0 (en CentOS 7).
La publicación aquí da algunas explicaciones:
Las funciones matemáticas a las que llama se implementan mediante funciones integradas del compilador
Ver también:
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 al compilador (realmente el enlazador) para vincularlas.
EDITAR: después de leer algunas de las otras respuestas y comentarios, creo que el referencia libc.a y la referencia libm que vincula a ambos tienen mucho que decir sobre por qué los dos están separados.
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 lo son, lo que puede resultar confuso, pero la regla general es esta: la biblioteca C contiene aquellas funciones que ANSI dicta que deben existir, por lo que no necesita el -lm si solo usa funciones ANSI. Por el contrario, ‘libm.a’ contiene más funciones y admite funciones adicionales, como la devolución de llamada de matherr y el cumplimiento de varios estándares alternativos de comportamiento en caso de errores de FP. Ver la sección libm, para más detalles.