Не визначене посилання на `pow 'та` floor'


124

Я намагаюсь зробити простий калькулятор напруги на C, але при компілюванні gccмені кажуть, що мені не вистачає функцій пороху та підлоги. Що не так?

Код:

#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

Оскільки точність плаваючої точки не нескінченна, це дасть неправильні відповіді на не такі великі значенняn
vonbrand


Здається, що існує ще простіше рішення, просто використовуйте g ++ натомість: g ++ fib.c -o fibo
OrenIshShalom

Відповіді:


242

Вам потрібно скласти прапор посилання -lm, як це:

gcc fib.c -lm -o fibo

Це дозволить gcc зв’язати ваш код з математичною lib. Просто не забудьте поставити прапор після об’єктів, які ви хочете зв’язати.


7
Чи можете ви поясніть, як розробити лист, який слід поставити після -l?
Габріеле Cirulli

48
Загляньте в / lib або / usr / lib. Усі бібліотеки названі lib<name>.aабо lib<name>.so- це "<ім'я>", яке ви ставите після -l. У цьому випадку математична бібліотека називається libm.so, тому ми її називаємо -lm.
Ams

3
Дякую! Я гуглив протягом останніх 30 хвилин, і це перша посилання, яка сказала про зв'язок бібліотек після об'єктів
Дейв Багданов

Ви також можете скористатися LD_PRELOAD, щоб повідомити ld-програмісту для введення часу, щоб включити libm.so в карту пам'яті та таблицю символів цього процесу, тому ці символи завантажуються, і все працює, як очікувалося
дебюти

Дякую за відповідь. Але хтось може мені сказати, чому у випадку з кодами з кількома рядками це нормально, навіть якщо я не включаю -lm під час компіляції?
MItrajyoti Kusari

24

Додайте -lm до своїх параметрів посилання, оскільки pow () та floor () є частиною математичної бібліотеки:

gcc fib.c -o fibo -lm

9

На користь тому, хто читає це пізніше, вам потрібно пов’язати це, як сказав Фред:

gcc fib.c -lm -o fibo

Один хороший спосіб дізнатися, до якої бібліотеки потрібно зв’язатись, перевіривши чоловічу сторінку, якщо така існує. Наприклад, man powіman floor вони вам скажуть:

Посилання з -lm .

Пояснення зв’язку математичної бібліотеки в програмуванні на С - Зв'язування в С


8

Що стосується відповіді, наданої Нечітким:

Мені насправді довелося зробити дещо інше.

Проект -> Властивості -> C / C ++ Build -> Settings -> GCC C Linker -> Libraries

Клацніть маленьку зелену піктограму Додати, введіть m і натисніть кнопку ОК. Все, що знаходиться у цьому вікні, автоматично застосовується до нього, оскільки це бібліотека.


6

Знайти точку, куди слід додати -lm в Eclipse-IDE, справді жахливо, тому мені знадобилося певний час.

Якщо хтось також використовує Edlipse, ось як додати команду:

Проект -> Властивості -> C / C ++ Build -> Налаштування -> GCC C Linker -> Miscelleaneous -> Прапор Linker: у цьому полі додайте команду -lm


0

Усі відповіді, наведені вище, є неповними. Проблема тут полягає в лінкері, 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прапор linker, з 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прапор після всіх інших прапорів та параметрів, щоб бути впевненим.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.