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

На этот вопрос уже есть ответ:

неопределенная ссылка на sqrt (или другие математические функции) 4 ответа

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

#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 изнутриmain функция, и те работают отлично. Я, должно быть, делаю что-то явно не так - но что это?

 Edwin Buck15 февр. 2011 г., 16:36
@ peoro, меня это не удивит. Это очень распространенная «забытая» библиотека.
 peoro15 февр. 2011 г., 16:13

Ответы на вопрос(4)

У меня все равно есть проблема с добавлением -lm

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

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

Так что вы должны указать библиотеки после.

 Lorenzo Dematté14 нояб. 2013 г., 09:47
Это проблема, которая давала сбои в gcc с тех пор :) Я думал, что пять лет и два основных релиза вылечили бы его, но он все еще здесь! Забавно
 Santi12 сент. 2015 г., 15:04
У меня тоже была та же проблема, когда я подал в суд на последнюю версию gcc 4.9
 Pockets12 янв. 2017 г., 19:43
Рад сообщить, что этого не происходит с gcc 5.4 или gcc 6.2.1.
 Jonathan Leffler26 авг. 2017 г., 22:02
Всегда связывайте библиотеки после объектных файлов. Это всегда работает. Связывание библиотек перед объектными файлами иногда работает, а иногда нет. (Есть случайные исключения - но они встречаются очень редко, и вы будете знать, когда это уместно и что делать, потому что руководства по используемой вами библиотеке скажут вам, или потому что вы написали руководство.)

$ gcc -Wall foo.c -o foo -lm 
Решение Вопроса

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

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

Вкомментари, LinuxD спрашивает:

Зачемsin() в<math.h> нам нужно-lmпция @ явно; но не дляprintf() в<stdio.h>?

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

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

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

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

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

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

На причины этого разделения повлиял ряд факторов:

The UNIX войны привело к увеличению расхождений с оригинальным предложением AT & T UNIX. Количество платформ UNIX добавило трудностей в разработке программного обеспечения для операционной системы. Попытка определить наименьший общий знаменатель для разработчиков программного обеспечения, называется 1988 POSIX. Разработчики программного обеспечения запрограммированы в соответствии со стандартом POSIX для предоставления своего программного обеспечения в «POSIX-совместимых системах», чтобы охватить больше платформ.лиенты @UNIX требовали «UNIX-системы», совместимые с POSIX, для запуска программного обеспечения.

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

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

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

 linuxD21 мар. 2013 г., 06:55
why для sin (math.h), нам явно нужна опция -lm, но не для printf () fn, определенной в stdio.h, я сомневаюсь в возможностях компоновщика GNU. Как и в VCC он работает и на Mac тоже, как упоминалось flarn2006.
 Edwin Buck12 июл. 2017 г., 17:11
@ KeithThompson Добавил много к ответу, чтобы убить комментарий. Наслаждаться
 Jonathan Leffler26 авг. 2017 г., 21:52
Обратите внимание, что системная библиотека на Mac (под управлением Mac OS X или macOS) содержит математические функции. Есть библиотека для удовлетворения ссылок на-lm в сборках, но вам не нужно использовать-lm, чтобы связать математические функции. Основная проблема, приводившая к отделению математической библиотеки от остальных, заключалась в том, что процессоры не всегда имели встроенную функцию с плавающей запятой; были сопроцессоры с плавающей запятой (80387 и т. д.) и т. д., поэтому было много способов обеспечить функциональность (используя программные библиотеки с плавающей запятой или аппаратное обеспечение с разной поддержкой).
 Jonathan Leffler26 авг. 2017 г., 22:12
Также обратите внимание, что современная спецификация POSIX дляc99 «расширенное описание - стандартные библиотеки» определяет библиотеки несколько по-другому, отмечая, что содержание-lm (как один из множества других) может быть связан без необходимости явного упоминания в командной строке связывания. Цитата в ответе от SVID 4-е издание (от июля 1995 года). Это исторически актуально, но больше не является определяющим.

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

Ваш ответ на вопрос