Неопределенная ссылка на ' sin ' [дубликат]

этот вопрос уже есть ответ здесь:

у меня есть следующий код (разделенный до голых основ для этого вопроса):

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

double f1(double x)
{
    double res = sin(x);
    return 0;
}

/* The main function */
int main(void)
{
    return 0;
}

при компиляции с gcc test.c Я получаю следующую ошибку, и я не могу позаниматься почему:

/tmp/ccOF5bis.o: In function `f1':
test2.c:(.text+0x13): undefined reference to `sin'
collect2: ld returned 1 exit status

тем не менее, я написал различные тестовые программы, которые вызывают sin внутри

4 ответов


вы скомпилировали свой код со ссылками на правильную математику.H заголовочный файл, но при попытке связать его вы забыли включить математическую библиотеку. В результате вы можете скомпилировать свой .o объектные файлы, но не сборка исполняемого файла.

как Павел уже упоминал добавить "-lm " для связи с математической библиотекой на шаге, где вы пытаетесь создать исполняемый файл.

на комментарий, linuxD спрашивает:

почему sin() на <math.h>, нужно явно; но, не для printf() на <stdio.h>?

потому что обе эти функции реализованы как часть "Единой спецификации UNIX". Эта история этого стандарта интересна и известна многими именами (IEEE Std 1003.1, X/Open Portability Guide, POSIX, Spec 1170).

этот стандарт, специально выделяет " стандартную библиотеку C" подпрограммы из "стандартной математической библиотеки C" подпрограммы (стр. 277). Соответствующий отрывок копируется ниже:

Стандартная Библиотека C

стандартная библиотека C автоматически ищет cc для разрешения внешних ссылок. Эта библиотека поддерживает все интерфейсы базовой системы, определенные в Томе 1, за исключением Математические Процедуры.

Стандартная Математическая Библиотека C

этот поддержка библиотеки базовые системные математические процедуры, определенные в Томе 1. The -lm используется для поиска в этой библиотеке.

на рассуждения, стоящие за этим разделением, повлиял ряд факторов:

  1. на Unix wars привело к увеличению расхождения с оригинальным предложением AT & T UNIX.
  2. количество платформ UNIX добавило сложности в разработке программного обеспечения для операционной система.
  3. была предпринята попытка определить наименьший общий знаменатель для разработчиков программного обеспечения, называется 1988 POSIX.
  4. разработчики программного обеспечения, запрограммированные против стандарта POSIX, чтобы предоставить свое программное обеспечение на "POSIX совместимых системах" для достижения большего количества платформ.
  5. клиенты UNIX потребовали" совместимых с POSIX " систем UNIX для запуска программного обеспечения.

давления, которые подали в решение поставить -lm in другая библиотека, вероятно, включена, но не ограничивается:

  1. это кажется хорошим способом сохранить размер libc, так как многие приложения не используют функции, встроенные в математическую библиотеку.
  2. он обеспечивает гибкость в реализации математической библиотеки, где некоторые математические библиотеки полагаются на большие встроенные таблицы поиска, в то время как другие могут полагаться на меньшие таблицы поиска (вычислительные решения).
  3. для поистине применений ограниченных размером, оно позволяет переопределения математической библиотеки нестандартным способом (например, вытаскивание просто sin() и поместить его в пользовательскую библиотеку.

в любом случае, теперь это часть стандарта, чтобы не включаться автоматически как часть языка C, и именно поэтому вы должны добавить -lm.


у меня есть проблема в любом случае с-LM added

gcc -Wall -lm mtest.c -o mtest.o
mtest.c: In function 'f1':
mtest.c:6:12: warning: unused variable 'res' [-Wunused-variable]
/tmp/cc925Nmf.o: In function `f1':
mtest.c:(.text+0x19): undefined reference to `sin'
collect2: ld returned 1 exit status

недавно я обнаружил, что он не работает, если вы сначала укажете-lm. Порядок имеет значение:

gcc mtest.c -o mtest.o -lm

просто ссылка без проблем

таким образом, вы должны указать библиотеки.


вам нужно связаться с математической библиотеке libm:

$ gcc -Wall foo.c -o foo -lm 

У меня была та же проблема, которая ушла после того, как я перечислил свою библиотеку в последний раз: GCC prog.c-lm