C libm.a не нужно связывать при компиляции

Я пытался скомпилировать исходный файл, который включает в себя <math.h>, Однако мне удалось создать исполняемый файл, без ошибок без ссылки на libm.a,

Команда, которую я набрал, была gcc -Wall filename.c -o executablename

Мне сказали связать с внешними библиотеками (то есть / библиотеки, кроме libc.a)

В чем дело?

#include <math.h>
#include <stdio.h>

int main(void)
{
    double x = sqrt(2.0);
    printf ("The sqrt of 2 is: %f\n", x);
    return 0;
}

3 ответа

Вызываемые вами математические функции реализуются встроенными функциями компилятора. Попробуйте следующее, если хотите увидеть сообщение об ошибке:

gcc -fno-builtin -Wall filename.c -o executablename

Например, на моей платформе (Ubuntu 14.04.3 LTS) я получаю следующее сообщение об ошибке:

$ cat x.c
#include <math.h>
#include <stdio.h>

int main(void)
{
    double x = sqrt(2.0);
    printf ("The sqrt of 2 is: %f\n", x);
    return 0;
}
$ gcc -fno-builtin x.c
/tmp/ccpjG2Pb.o: In function `main':
x.c:(.text+0x1c): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status

Некоторые компиляторы, как текущий clang на OS X (который маскируется под gcc) не нужно указывать, чтобы связать ваш исполняемый файл с математической библиотекой.

clang на OS X свяжет ваш исполняемый файл с /usr/lib/libSystem.B.dylib (и только это для простой программы). Эта библиотека в свою очередь использует библиотеку /usr/lib/system/libsystem_m.dylib которая является математической библиотекой.

Функции в <math.h> (или предпочтительнее <tgmath.h>) являются частью библиотеки C, как и многие другие функции. Это зависит от платформы, если все функции в библиотеке C на самом деле связаны в одной библиотеке или по отдельности в нескольких чанках.

В древние времена размер библиотек был проблемой для времени компоновки, чем больше была библиотека, тем больше времени требовалось для компоновки исполняемых файлов, которые имели много неразрешенных символов. Эти времена давно прошли, но разделение на некоторых платформах в libc.a а также libm.a преобладает.

Если ваша платформа не нужна -lm для ссылки на него должна быть фиктивная (пустая) версия libm.a просто в том, что в командной строке ссылки нет ошибки. Это, например, случай с библиотекой musl C, которая лежит в основе Alpine Linux.

Другие вопросы по тегам