`` Pow '' ve `` floor '' için tanımlanmamış referans


124

C'de basit bir fibonacci hesap makinesi yapmaya çalışıyorum ama derleme yaparken gccbana pow ve floor işlevlerini kaçırdığımı söylüyor. Sorun nedir?

Kod:

#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));
}

Çıktı:

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

Kayan nokta hassasiyeti sonsuz olmadığından, bu çok büyük olmayan değerler için yanlış cevaplar verecektirn
vonbrand


Bir daha da kolay çözüm, basitçe yerine ++ g kullanmak varolduğunu görünüyor: g ++ fib.c -o codefibo
OrenIshShalom

Yanıtlar:


242

Aşağıdaki -lmgibi bağlantı bayrağıyla derlemeniz gerekir :

gcc fib.c -lm -o fibo

Bu, gcc'ye kodunuzu matematik kütüphanesine bağlamasını söyleyecektir. Sadece bayrak koymak emin olun sonra Bağlantıya istediğiniz nesnelerin.


7
-L harfinin sonrasına yazılacak mektubu nasıl çıkaracağınızı açıklar mısınız?
Gabriele Cirulli

48
/ Lib veya / usr / lib dizinlerine bakın. Kitaplıkların tümü adlandırılmıştır lib<name>.aveya lib<name>.so- bu -l,. Bu durumda matematik kitaplığı adlandırılır libm.so, bu yüzden ona diyoruz -lm.
ams

3
Teşekkürler! Son 30 dakikadır googling yapıyorum ve bu, kütüphaneleri nesnelerden sonra bağladığını söyleyen ilk referans
Dave Baghdanov

LD_PRELOAD'yi ayrıca, ld çalışma zamanı bağlayıcısına işlemin bellek haritasına ve sembol tablosuna libm.so eklemesini söylemek için de kullanabilirsiniz, böylece bu semboller yüklenir ve her şey beklendiği gibi çalışır
debuti

Cevap için teşekkürler. Ama kimse bana derleme sırasında -lm eklemesem bile neden birkaç satırlık kodlar olması durumunda sorun olmadığını söyleyebilir mi?
MItrajyoti Kusari

24

Pow () ve floor () matematik kitaplığının bir parçası olduğundan bağlantı seçeneklerinize -lm ekleyin:

gcc fib.c -o fibo -lm

9

Bunu daha sonra okuyan birinin yararı için, Fred'in dediği gibi buna karşı bağlantı kurmanız gerekir:

gcc fib.c -lm -o fibo

Hangi kitaplığı bağlamanız gerektiğini bulmanın iyi bir yolu, varsa man sayfasını kontrol etmektir. Örneğin, man powve man floorikisi de size şunu söyleyecektir:

İle bağlantı kurun -lm.

C programlamada matematik kitaplığını bağlamak için bir açıklama - C'de bağlama


8

Fuzzy'nin verdiği cevapla ilgili olarak:

Aslında biraz farklı bir şey yapmam gerekiyordu.

Proje -> Özellikler -> C / C ++ Oluşturma -> Ayarlar -> GCC C Bağlayıcı -> Kitaplıklar

Küçük yeşil ekle simgesine tıklayın, m yazın ve tamam'a basın. Bu penceredeki her şey, bir kütüphane olduğu için otomatik olarak -l uygulanmıştır.


6

Eclipse-IDE'de -lm'nin nereye ekleneceğini bulmak gerçekten korkunç, bu yüzden biraz zaman aldı.

Başka biri de Edlipse kullanıyorsa, komutu şu şekilde ekleyebilirsiniz:

Proje -> Özellikler -> C / C ++ Oluşturma -> Ayarlar -> GCC C Bağlayıcı -> Çeşitli -> Bağlayıcı bayrakları: bu alana -lm komutunu ekleyin


0

Yukarıdaki tüm cevaplar eksiktir, buradaki sorun ldderleyici yerine bağlayıcıda yatmaktadır collect2: ld returned 1 exit status. fib.cNesnenizi derlerken :

$ gcc -c fib.c
$ nm fib.o
0000000000000028 T fibo
                 U floor
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
                 U pow
                 U printf

Nerede nmnesne dosyasından listeleri sembolleri. Bunun bir hata olmadan derlenmiş olduğunu görebilirsiniz, ancak pow, floorve printfben çalıştırılabilir bu bağlantı için çalışacağız eğer fonksiyonlar şimdi, tanımlanmamış referansları var:

$ 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

Ben de benzer çıktılar alıyorum. Bunu çözmek için, linker'a referansları nerede arayacağımı söylemem gerekiyor powve floorbu amaçla kütüphaneden gelen linker -lbayrağını kullanacağım .mlibm.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__

Artık fonksiyonlar, görebiliyorum pow, floorbağlantılıdır GLIBC_2.2.5.

Parametreler sırası da önemlidir, sisteminiz varsayılan olarak paylaşılan kitaplıkları kullanacak şekilde yapılandırılmadıkça, benim sistemim öyle değildir, bu nedenle:

$ 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

Not -lmnesne dosyası önce bayrağı. Sonuç olarak, -lmemin olmak için diğer tüm işaretlerin ve parametrelerin arkasına bayrak ekleyin .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.