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

У меня есть этот простой код:

max = (int) sqrt (number);

а у меня в шапке:

#include <math.h>

Но приложение по-прежнему говорит о неопределенной ссылке на sqrt. Вы видите здесь какую-то проблему? Вроде все должно быть в порядке.


person Waypoint    schedule 09.03.2011    source источник
comment
Кто жалуется, компоновщик или компилятор? Если вы можете опубликовать точную ошибку, это, вероятно, прояснит ситуацию.   -  person Tommy    schedule 09.03.2011
comment
компилятор пишет эту жалобу, проблема в том, что приложение даже не построено...   -  person Waypoint    schedule 09.03.2011
comment
Проблема не в вашей программе, а в реализации вашей системы библиотеки C. Он по-прежнему следует устаревшим соглашениям 1970-х/1980-х годов, когда математические функции находятся в отдельной библиотеке и по умолчанию не связаны.   -  person R.. GitHub STOP HELPING ICE    schedule 09.03.2011
comment
Связано: stackoverflow.com/questions/1033898/   -  person Nate Eldredge    schedule 11.02.2021


Ответы (5)


Вы можете обнаружить, что вам нужно связать математические библиотеки в любой системе, которую вы используете, например:

gcc -o myprog myprog.c -L/path/to/libs -lm
                                       ^^^ - this bit here.

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

В противном случае вам нужно будет показать нам свой код, команду компиляции и платформу, на которой вы работаете (операционная система, компилятор и т. д.).

Следующий код компилируется и компонуется нормально:

#include <math.h>
int main (void) {
    int max = sqrt (9);
    return 0;
}

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

Так, например, учитывая команды:

gcc -o plugh plugh.o -lxyzzy
gcc -o plugh -lxyzzy plugh.o

а plugh.o требует что-то из библиотеки xyzzy, второе может работать не так, как вы ожидаете. В точке, где вы перечисляете библиотеку, нет неразрешенных символов, которые нужно удовлетворить.

А когда появляются неразрешенные символы из plugh.o действительно, уже слишком поздно.

person paxdiablo    schedule 09.03.2011
comment
извините, я написал это плохо, конечно, это включено... проблема в том, что это приложение даже не собрано... - person Waypoint; 09.03.2011
comment
У меня есть добавление -lm через сборку, теперь у меня есть другие ошибки, но это решено! Благодарность - person Waypoint; 09.03.2011
comment
@paxdiablo: а в случае µClibc для csqrt? - person user2284570; 19.05.2015
comment
@user2284570 user2284570, похоже, это лучше было бы опубликовать как вопрос (Как мне связать математические библиотеки для uClibc? Или что-то в этом роде). Вопрос видят намного больше людей, чем комментарий. - person paxdiablo; 19.05.2015
comment
Также обратите внимание на порядок связанных библиотек. Я обнаружил, что у меня был -lm слишком рано в командной строке и что его перемещение в конец устраняет связанные сообщения об ошибках. Это также, похоже, зависит от версии gcc (некоторые старые версии не возражали). - person Kevin Bullaughey; 10.07.2015
comment
Хороший указатель @KevinBullaughey Мне также пришлось переместить еще одну опцию ссылки на задний план (-lpthread). - person Tony Martin; 07.03.2016
comment
@paxdiablo очень хорошо объяснил! особенно последние 2 абзаца - person Jack; 13.04.2016

Я полагаю, вы импортировали math.h с #include <math.h>

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

Если вы просто пытаетесь скомпилировать один файл с помощью gcc, просто добавьте -lm в свою командную строку, в противном случае предоставьте некоторую информацию о процессе сборки.

person krtek    schedule 09.03.2011
comment
он не будет построен, потому что вы неправильно связываете, просто попробуйте добавить -lm к вашей команде сборки. - person krtek; 09.03.2011
comment
В случае µClibc для csqrt()? - person user2284570; 19.05.2015

Просто добавление #include <math.h> в исходный файл c и -lm в Makefile в конце будет работать для меня.

    gcc -pthread -o p3 p3.c -lm
person Hassan Rahman    schedule 09.07.2017
comment
Извините, оператор включения был скрыт из-за переполнения стека. Я только что сделал код, и теперь он работает. - person Hassan Rahman; 13.07.2017

Вот мое наблюдение, во-первых, вам нужно включить заголовок math.h как функцию sqrt(), объявленную в заголовочном файле math.h. Например,

#include <math.h>

во-вторых, если вы прочитаете справочную страницу sqrt, вы заметите эту строку связать с -lm.

#include <math.h> /* header file you need to include */

double sqrt(double x); /* prototype of sqrt() function */

Link with -lm. /* Library linking instruction */

Но приложение по-прежнему говорит о неопределенной ссылке на sqrt. Вы видите здесь какую-то проблему?

Ошибка компилятора верна, так как вы не связали свою программу с библиотекой lm, и компоновщик не может найти ссылку на sqrt(), вам нужно связать ее явно. Например,

gcc -Wall -Wextra -Werror -pedantic test.c -lm
person Achal    schedule 28.07.2019

У меня была та же проблема, но я просто решил ее, добавив -lm после команды, которая запускает мой код. Пример. код gcc.c -lm

person Mohamed Mnete    schedule 05.02.2017
comment
Чем это отличается от других ответов, опубликованных несколько лет назад? - person grooveplex; 29.07.2019