2012-04-29 27 views
9

thể trùng lặp:
gcc: why the -lm flag is needed to link the math library?Tại sao bạn cần một 'tùy chọn biên dịch -lm` rõ ràng

Nói chung, để sử dụng bất kỳ các hàm toán học ngoài bao gồm tiêu đề file math.h bạn phải liên kết với tùy chọn liên kết -lm. -l ở đây có nghĩa là tùy chọn trình liên kết để tìm kiếm thư viện cụ thể libm.o.

Câu hỏi của tôi là

Tại sao GCC không bao gồm thư viện này theo mặc định? Có phải vì thư viện sử dụng rất nhiều bộ xử lý toán học và nó đòi hỏi phải thêm một chút mã để khởi tạo việc khởi tạo điểm nổi (tôi có thể sử dụng thuật ngữ sai ở đây)?

Note

Tôi đã xem xét tất cả các câu trả lời được đề cập trong liên kết http://stackoverflow.com. Điều này không có ý nghĩa với tôi. Có ba lý do cơ bản được gán cho

  1. Thư viện chuẩn được đảm bảo khả dụng. Việc liên kết các thư viện posix khác như pthread rõ ràng có ý nghĩa, nhưng tại sao chúng ta phải tạo một liên kết rõ ràng cho một thư viện chuẩn. Ngay cả lý do lịch sử cũng không rõ ràng lắm.
  2. Tại sao libm được tách khỏi libc?
  3. Tại sao chúng ta vẫn kế thừa những hành vi này trong các trình biên dịch gcc gần đây? Điều gì đơn giản nó đạt được? Đây là những gì tôi đã thử nghiệm, không có libm và với libm. The One mà không libm, tôi đã viết phiên bản riêng của tôi về Pow

Dưới đây là ví dụ

[email protected]:~/Projects/GIPL6_2$ ls -1 Test_*|xargs -I{} sh -c "echo {} && echo "-----------------" && cat {}" 
Test_withlibm.c 
----------------- 
#include<stdio.h> 
#include<math.h> 
int main() { 
    int i=20; 
    double output1=pow(2.618033988749895,i); 
    return 0; 
    } 
Test_withoutlibm.c 
----------------- 
#include<stdio.h> 
#include<math.h> 
double Pow(double _X, int _Y) { 
    double _Z = 1; 
    for (; _Y; _X *= _X) { 
    if (_Y & 1) _Z *= _X; 
    _Y >>= 1; 
    } 
    return _Z; 
    } 
int main() { 
    int i=20; 
    double output1=Pow(2.618033988749895,i); 
    return 0; 
    } 
[email protected]:~/Projects/GIPL6_2$ gcc Test_withlibm.c -lm -o Main_withlibm.o 
[email protected]:~/Projects/GIPL6_2$ gcc Test_withoutlibm.c -o Main_withoutlibm.o 
[email protected]:~/Projects/GIPL6_2$ objdump -d Main_withoutlibm.o|wc -l 
261 
[email protected]:~/Projects/GIPL6_2$ objdump -d Main_withlibm.o|wc -l 
241 
+2

Lý do lịch sử, tôi đoán vậy. Trình liên kết phải dễ dàng không thể liên kết các hàm không được sử dụng. MSVC không cần một libm hoặc cho bạn sử dụng các hàm toán học. – Joey

+0

Bạn không cần nó với C++. – Mat

Trả lời

7

Nó là để chứa hệ thống (chủ yếu là nhúng), nơi toán học dấu chấm động là không thể hoặc cần thiết. Đó là loại lịch sử thực sự nhưng đừng quên rằng gcc và hầu hết các trình biên dịch C khác được viết trong một thời điểm mà 386SX được coi là một bộ xử lý hiệu năng cao.

Để đưa ra một ví dụ, khi tôi vẫn làm việc trong máy tính nhúng, chúng tôi đã sử dụng các trình biên dịch chuẩn (Microsoft và Borland) để tạo mã cho bộ xử lý của chúng tôi (Z80, 80186 và 68030).Nếu các trình biên dịch có mặc định được liên kết với thư viện toán, chúng tôi sẽ gặp rắc rối vì không có hệ thống nào của chúng tôi có khả năng điểm động hoặc thậm chí cần đến nó.

Đúng là 30 năm sau đó có vẻ ngớ ngẩn nhưng lý do là âm thanh tại thời điểm đó.

1

Có rất nhiều thư viện bạn có thể muốn, và libm chỉ là một trong số họ.
Đối với mỗi loại này, bạn có thể hỏi tại sao nó không được bao gồm theo mặc định.

Có lẽ libm hữu ích hơn những người khác, nhưng vẫn còn, C thích giữ mọi thứ đơn giản - bạn muốn có thư viện, sử dụng -l để sử dụng.

+5

Nhưng điều duy nhất về 'libm' là nó là một phần của thư viện chuẩn C. AFAIK, đây là phần duy nhất của thư viện chuẩn C không được liên kết theo mặc định. –

+1

@OliCharlesworth, điểm tốt. Nó sẽ là tốt đẹp nếu "tiêu chuẩn" và "liên kết theo mặc định" là điều tương tự. – ugoren

1

lý do lịch sử

Những lý do libclibm được tách ra và bạn phải chỉ định -lm trên dòng lệnh là lý do lịch sử vì libm cũng được sử dụng bởi trình biên dịch Fortran.

+0

Vì vậy, cùng một libm có thể được chia sẻ bởi Fortran và C là lý do để tách biệt? Khi liên kết chương trình Fortran, chúng ta có phải liên kết nó một cách rõ ràng với '-lm' khi chúng ta đi với gcc không? – Abhijit

Các vấn đề liên quan