¿Por qué tengo que vincularme explícitamente con libm? [duplicate]

4 minutos de lectura

avatar de usuario
lindelof

Posible duplicado:

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

Cuando escribo un programa que usa funciones del math.h biblioteca, ¿por qué tengo que vincular explícitamente a libm a pesar de que son parte de la biblioteca estándar de C?

Por ejemplo, cuando quiero usar el sin() función que necesito #include <math.h> pero también necesito pasar -lm a CCG. Pero para cualquier otra biblioteca de la biblioteca estándar, no tengo que hacer eso. ¿Por qué la diferencia?

avatar de usuario
pmg

En los viejos tiempos, los enlazadores eran lentos y separar el código matemático en su mayoría no utilizado del resto hacía que el proceso de compilación fuera más rápido. La diferencia no es tan grande hoy, por lo que puede agregar el -lm opción a su configuración de compilador predeterminada.


Tenga en cuenta que el encabezado <math.h> (o cualquier otro encabezado) no contiene código. Contiene información sobre el código, específicamente cómo para llamar funciones. El código en sí está en una biblioteca. Quiero decir, su programa no usa el <math.h> biblioteca”usa la librería matemática y usa los prototipos declarados en el <math.h> encabezamiento.

Es la misma razón por la que tienes que vincular explícitamente a libpthread en la mayoría de las implementaciones. Cuando se agrega algo nuevo y aterrador a la biblioteca estándar, generalmente se implementa primero como una biblioteca complementaria separada que anula algunos de los símbolos en la implementación de la biblioteca estándar anterior con versiones que se ajustan a los nuevos requisitos, al tiempo que agrega muchos nuevas interfaces. No me sorprendería si algunas implementaciones históricas tuvieran versiones separadas de printf en libm para impresión de punto flotante, con una versión “ligera” en la parte principal libc sin punto flotante. Este tipo de implementación en realidad se menciona y se recomienda para sistemas pequeños en el documento de fundamentos de ISO C, si no recuerdo mal.

Por supuesto, a largo plazo, separar la biblioteca estándar de esta manera genera muchos más problemas que beneficios. La peor parte es probablemente el aumento del tiempo de carga y el uso de memoria para los programas vinculados dinámicamente.

En realidad, la razón por la que normalmente no necesita vincular contra libm para la mayoría de las funciones matemáticas es que su compilador las integra. Su programa no se vincularía en una plataforma donde este no sea el caso.

  • La mayoría de libm es imposible en línea a menos que su límite de función en línea sea de varios KB o haya habilitado un truco como -ffast-math que permite al compilador generar código incorrecto pero rápido.

    – R.. GitHub DEJA DE AYUDAR A ICE

    24 de marzo de 2011 a las 13:48

  • Bueno, en x86 el seno y el coseno se implementan dentro de la FPU y se puede acceder a ellos con una sola instrucción, por lo que la inserción tiene mucho sentido aquí. Un programa que solo usa sin() no será necesario enlazar contra libm en x86, ocultando así la referencia de la biblioteca que falta.

    – Simón Richter

    24 de marzo de 2011 a las 15:21

  • ¿Estás seguro de que la FPU sin la instrucción puede implementar directamente sin()? Si no me equivoco, primero necesita un paso de reducción de argumento no trivial.

    – R.. GitHub DEJA DE AYUDAR A ICE

    24 de marzo de 2011 a las 17:01

  • De acuerdo, ese fue un mal ejemplo, mis disculpas. fabs() es mejor en x86. Mi punto original sigue en pie: si todas las funciones que usa están en línea, entonces el programa se vinculará y funcionará bien incluso si la biblioteca matemática no está vinculada, sin embargo, eso no es portátil por razones obvias.

    – Simón Richter

    24 de marzo de 2011 a las 17:25

  • @SimonRichter Los mayores entre nosotros recuerdan los tiempos en que los procesadores x86 no tenían una FPU integrada. AFAIK, el primero con FPU incorporado fue el i486, e incluso ese tenía una versión lisiada sin FPU (llamada i486SX). Además, el OP no solicitó x86 explícitamente.

    – Binarus

    14 de noviembre de 2017 a las 8:06


¿Ha sido útil esta solución?