Подтвердить что ты не робот

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

4b9b3361

Ответ 1

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

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

В comment linuxD спрашивает:

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

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

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

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

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

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

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

В основе этих разделов лежал ряд факторов:

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

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

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

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

Ответ 2

У меня есть проблема в любом случае с добавлением -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

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

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

Ответ 3

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

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

Ответ 4

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