Tham chiếu không xác định đến 'pow' và 'sàn'


124

Tôi đang cố gắng tạo một máy tính fibonacci đơn giản bằng C nhưng khi biên dịch gccnói với tôi rằng tôi thiếu các hàm pow và tầng. Chuyện gì vậy?

Mã:

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

Đầu ra:

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

Vì độ chính xác của dấu phẩy động không phải là vô hạn, điều này sẽ đưa ra câu trả lời sai cho các giá trị không quá lớnn
vonbrand


Dường như một giải pháp dễ dàng hơn tồn tại, chỉ cần sử dụng g ++ thay vì: g ++ fib.c -o fibo
OrenIshShalom

Câu trả lời:


242

Bạn cần biên dịch với cờ liên kết -lm, như sau:

gcc fib.c -lm -o fibo

Điều này sẽ yêu cầu gcc liên kết mã của bạn với lib toán học. Chỉ cần đảm bảo đặt cờ sau các đối tượng bạn muốn liên kết.


7
Bạn có thể vui lòng giải thích làm thế nào để làm ra các ký tự để đặt sau -l?
Gabriele Cirulli

48
Tìm trong / lib hoặc / usr / lib. Tất cả các thư viện đều được đặt tên lib<name>.ahoặc lib<name>.so- đó là "<name>" mà bạn đặt sau -l. Trong trường hợp này, thư viện toán học được đặt tên libm.so, vì vậy chúng tôi gọi nó -lm.
ams

3
Cảm ơn! Tôi đã googling trong 30 phút vừa qua và đây là tài liệu tham khảo đầu tiên mà nói để liên kết các thư viện sau khi các đối tượng
Dave Baghdanov

Bạn cũng có thể sử dụng LD_PRELOAD để yêu cầu trình liên kết thời gian chạy ld bao gồm libm.so trong bản đồ bộ nhớ và bảng ký hiệu của quy trình, để các ký hiệu này được tải và mọi thứ hoạt động như mong đợi
debuti

Cảm ơn vì câu trả lời. Nhưng ai đó có thể cho tôi biết tại sao trong trường hợp mã có một vài dòng, nó không sao ngay cả khi tôi không bao gồm -lm trong khi biên dịch?
MItrajyoti Kusari

24

Thêm -lm vào các tùy chọn liên kết của bạn, vì pow () và floor () là một phần của thư viện toán học:

gcc fib.c -o fibo -lm

9

Vì lợi ích của bất kỳ ai đọc nội dung này sau này, bạn cần phải liên kết chống lại nó như Fred đã nói:

gcc fib.c -lm -o fibo

Một cách hay để tìm ra thư viện nào bạn cần liên kết là kiểm tra trang người dùng nếu có. Ví dụ, man powman floorcả hai sẽ cho bạn biết:

Liên kết với -lm.

Giải thích liên kết thư viện toán học trong lập trình C - Liên kết trong C


8

Liên quan đến câu trả lời do Fuzzy cung cấp:

Tôi thực sự đã phải làm một cái gì đó hơi khác một chút.

Dự án -> Thuộc tính -> Bản dựng C / C ++ -> Cài đặt -> Trình liên kết GCC C -> Thư viện

Nhấp vào biểu tượng thêm màu xanh lá cây nhỏ, nhập m và nhấn ok. Mọi thứ trong cửa sổ này tự động có -l áp dụng cho nó vì nó là một thư viện.


6

Để tìm điểm nơi thêm -lm trong Eclipse-IDE thực sự rất kinh khủng, vì vậy tôi đã mất một khoảng thời gian.

Nếu ai đó cũng sử dụng Edlipse, đây là cách để thêm lệnh:

Dự án -> Thuộc tính -> Xây dựng C / C ++ -> Cài đặt -> Trình liên kết GCC C -> Sai lệch -> Cờ trình liên kết: trong trường này thêm lệnh -lm


0

Tất cả các câu trả lời trên đều chưa đầy đủ, vấn đề ở đây nằm ở trình liên kết ldhơn là trình biên dịch collect2: ld returned 1 exit status. Khi bạn đang biên dịch fib.cthành đối tượng:

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

Nơi nmliệt kê các ký hiệu từ tệp đối tượng. Bạn có thể thấy rằng đây đã được biên soạn mà không có lỗi, nhưng pow, floorprintfcác chức năng có tài liệu tham khảo không xác định, bây giờ nếu tôi sẽ cố gắng liên kết này để thực thi:

$ 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

Tôi nhận được đầu ra tương tự như bạn nhận được. Để giải quyết vấn đề đó, tôi cần cho người liên kết biết nơi tìm kiếm các tham chiếu powfloor, cho mục đích này, tôi sẽ sử dụng -lcờ trình liên kết mđến từ libm.sothư viện.

$ 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__

Bây giờ bạn có thể thấy, các chức năng pow, floorđược liên kết với GLIBC_2.2.5.

Thứ tự tham số cũng quan trọng, trừ khi hệ thống của bạn được định cấu hình để sử dụng các thư viện dùng chung theo mặc định, hệ thống của tôi thì không, vì vậy khi tôi phát hành:

$ 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

Ghi chú -lmcờ trước tệp đối tượng. Vì vậy, kết luận, hãy thêm -lmcờ sau tất cả các cờ khác và các tham số, để chắc chắn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.