Неопределенная ссылка на `pow'и`floor'
Я пытаюсь сделать простой калькулятор Фибоначчи в C, но при компиляции gcc
говорит мне, что мне не хватает функций pow и floor. В чем дело?
Код:
#include <stdio.h>
#include <math.h>
int fibo(int n);
int main() {
printf("Fib(4) = %d", fibo(4));
return 0;
}
int fibo(int n) {
double phi = 1.61803399;
return (int)(floor((float)(pow(phi, n) / sqrt(5)) + .5f));
}
Выход:
gab@testvm:~/work/c/fibo$ gcc fib.c -o fibo
/tmp/ccNSjm4q.o: In function `fibo':
fib.c:(.text+0x4a): undefined reference to `pow'
fib.c:(.text+0x68): undefined reference to `floor'
collect2: ld returned 1 exit status
5 ответов
Вам нужно скомпилировать с флагом ссылки -lm
, как это:
gcc fib.c -lm -o fibo
Это скажет gcc связать ваш код с математической библиотекой. Просто не забудьте поставить флаг после объектов, которые вы хотите связать.
Добавьте -lm к вашим параметрам ссылок, так как pow() и floor() являются частью математической библиотеки:
gcc fib.c -o fibo -lm
Чтобы кто-нибудь прочел это позже, вам нужно дать ссылку на него, как сказал Фред:
gcc fib.c -lm -o fibo
Один хороший способ узнать, на какую библиотеку вам нужно ссылаться, - это проверить страницу руководства, если она существует. Например, man pow
а также man floor
оба скажут вам:
Связать с -lm
,
Объяснение для связи математической библиотеки в программировании на C - Связывание в C
Что касается ответа, предоставленного Fuzzy:
Я действительно должен был сделать что-то немного другое.
Проект -> Свойства -> Сборка C/C++ -> Настройки -> GCC C Linker -> Библиотеки
Нажмите маленький зеленый значок добавления, введите m и нажмите ОК. Все в этом окне автоматически применяет -l, поскольку это библиотека.
Найти точку, где добавить -lm в Eclipse-IDE, действительно ужасно, поэтому мне потребовалось некоторое время.
Если кто-то еще также использует Edlipse, вот способ добавить команду:
Проект -> Свойства -> Сборка C/C++ -> Настройки -> GCC C Linker -> Разное -> Флажки компоновщика: в этом поле добавьте команду -lm
Все ответы выше неполны, проблема здесь в компоновщике ld
а не компилятор collect2: ld returned 1 exit status
. Когда вы составляете свойfib.c
для объекта:
$ gcc -c fib.c
$ nm fib.o
0000000000000028 T fibo
U floor
U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
U pow
U printf
где nm
перечисляет символы из объектного файла. Вы можете видеть, что это было скомпилировано без ошибок, ноpow
, floor
, а также printf
у функций есть неопределенные ссылки, теперь, если я попытаюсь связать это с исполняемым файлом:
$ gcc fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status
Я получаю тот же результат, что и вы. Чтобы решить эту проблему, мне нужно указать компоновщику, где искать ссылки наpow
, а также floor
, для этого я воспользуюсь компоновщиком -l
флаг с m
который исходит из libm.so
библиотека.
$ gcc fib.o -lm
$ nm a.out
0000000000201010 B __bss_start
0000000000201010 b completed.7697
w __cxa_finalize@@GLIBC_2.2.5
0000000000201000 D __data_start
0000000000201000 W data_start
0000000000000620 t deregister_tm_clones
00000000000006b0 t __do_global_dtors_aux
0000000000200da0 t
__do_global_dtors_aux_fini_array_entry
0000000000201008 D __dso_handle
0000000000200da8 d _DYNAMIC
0000000000201010 D _edata
0000000000201018 B _end
0000000000000722 T fibo
0000000000000804 T _fini
U floor@@GLIBC_2.2.5
00000000000006f0 t frame_dummy
0000000000200d98 t __frame_dummy_init_array_entry
00000000000009a4 r __FRAME_END__
0000000000200fa8 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
000000000000083c r __GNU_EH_FRAME_HDR
0000000000000588 T _init
0000000000200da0 t __init_array_end
0000000000200d98 t __init_array_start
0000000000000810 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000000800 T __libc_csu_fini
0000000000000790 T __libc_csu_init
U __libc_start_main@@GLIBC_2.2.5
00000000000006fa T main
U pow@@GLIBC_2.2.5
U printf@@GLIBC_2.2.5
0000000000000660 t register_tm_clones
00000000000005f0 T _start
0000000000201010 D __TMC_END__
Теперь вы можете видеть, функции pow
, floor
связаны с GLIBC_2.2.5
.
Порядок параметров также важен, если ваша система не настроена на использование общих библиотек по умолчанию, моя система нет, поэтому, когда я выдаю:
$ gcc -lm fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status
Запись -lm
флаг перед объектным файлом. В заключение добавим-lm
flag после всех остальных флагов и параметров, чтобы быть уверенным.