2012-04-29 10 views
9

Duplicar posible:
gcc: why the -lm flag is needed to link the math library?¿Por qué necesita una opción explícita compilador `-lm`

En términos generales, con el fin de utilizar cualquiera de las funciones matemáticas además de incluir la cabecera archivo math.h tiene que vincular con la opción del vinculador -lm. -l aquí significaría la opción del vinculador para buscar en la biblioteca específica libm.o.

Mi pregunta es

Por qué GCC no incluye esta biblioteca por defecto? ¿Se debe a que la biblioteca utiliza en gran medida el coprocesador matemático y requiere agregar el bit adicional de código para inicializar la inicialización de punto flotante (aquí puedo usar la terminología equivocada)?

Nota

Acabo de revisar todas las respuestas mencionadas en el enlace http://stackoverflow.com. Esto no tiene mucho sentido para mí. Hay tres razones básicas atribuidas

  1. Se garantiza que las bibliotecas estándar estarán disponibles. Vincular explícitamente otras bibliotecas posix como pthread tiene sentido, pero ¿por qué tenemos que hacer un enlace explícito para una biblioteca estándar? Incluso la razón histórica no es muy clara.
  2. ¿Por qué libm se separó de la libc?
  3. ¿Por qué seguimos heredando estos comportamientos en los recientes compiladores de gcc? ¿Qué simplicidad logra? Esto es lo que probé, sin libm y con libm. El Uno sin libm, he escrito mi propia versión de Pow

Aquí está el ejemplo

[email protected]:~/Projects/GIPL6_2$ ls -1 Test_*|xargs -I{} sh -c "echo {} && echo "-----------------" && cat {}" 
Test_withlibm.c 
----------------- 
#include<stdio.h> 
#include<math.h> 
int main() { 
    int i=20; 
    double output1=pow(2.618033988749895,i); 
    return 0; 
    } 
Test_withoutlibm.c 
----------------- 
#include<stdio.h> 
#include<math.h> 
double Pow(double _X, int _Y) { 
    double _Z = 1; 
    for (; _Y; _X *= _X) { 
    if (_Y & 1) _Z *= _X; 
    _Y >>= 1; 
    } 
    return _Z; 
    } 
int main() { 
    int i=20; 
    double output1=Pow(2.618033988749895,i); 
    return 0; 
    } 
[email protected]:~/Projects/GIPL6_2$ gcc Test_withlibm.c -lm -o Main_withlibm.o 
[email protected]:~/Projects/GIPL6_2$ gcc Test_withoutlibm.c -o Main_withoutlibm.o 
[email protected]:~/Projects/GIPL6_2$ objdump -d Main_withoutlibm.o|wc -l 
261 
[email protected]:~/Projects/GIPL6_2$ objdump -d Main_withlibm.o|wc -l 
241 
+2

Motivos históricos, supongo. El enlazador debe poder fácilmente no unir funciones que no se usan. MSVC tampoco necesita una libma para que pueda usar las funciones matemáticas. – Joey

+0

No lo necesita con C++. – Mat

Respuesta

7

Es para acomodar sistemas (principalmente incrustados) donde la matemática de coma flotante no es posible o necesaria. Es un poco histórico, pero no olvides que gcc y la mayoría de los otros compiladores de C se escribieron en un momento en el que un 386SX se consideraba un procesador de alto rendimiento.

Para dar un ejemplo, cuando todavía trabajaba en informática integrada, utilizamos compiladores estándar (Microsoft y Borland) para generar código para nuestros procesadores (Z80, 80186 y 68030).Si los compiladores se hubieran vinculado por defecto a la biblioteca matemática, habríamos tenido problemas ya que ninguno de nuestros sistemas tenía capacidades de punto flotante o incluso lo necesitaban.

Es verdad que 30 años después parece una tontería, pero la razón era sólida en ese momento.

1

Hay muchas bibliotecas que usted puede desear, y libm es sólo uno de ellos.
Para cada uno de estos, puede preguntar por qué no está incluido por defecto.

Tal vez libm es más útil que otros, pero aún así, C prefiere mantener las cosas simples: desea una biblioteca, use -l para usarla.

+5

Pero lo que es único acerca de 'libm' es que es parte de la biblioteca estándar de C. AFAIK, es la única parte de la biblioteca estándar C que no está vinculada por defecto. –

+1

@OliCharlesworth, buen punto. Sería bueno si "estándar" y "vinculado por defecto" fueran lo mismo. – ugoren

1

razones históricas

Las razones libc y libm están separados y hay que especificar -lm en la línea de comandos son razones históricas porque el libm también fue utilizado por el compilador Fortran.

+0

Entonces, ¿la misma libma puede ser compartida por Fortran y C fue la razón para separarse? Cuando vinculamos el programa Fortran, ¿tenemos que vincularlo explícitamente con '-lm' a medida que avanzamos con gcc? – Abhijit

Cuestiones relacionadas