簡體   English   中英

我在我的C程序中使用了pow()函數,但沒有鏈接到-lm它仍然有效。 為什么?

[英]I used pow() function in my C program but did not link to -lm it still worked. Why?

我正在讀一本關於海灣合作委員會的書。 它表示,對於任何C程序,默認情況下只鏈接標准庫。 由於pow()不在標准庫中,我將不得不使用-lm標志鏈接到它。 但是,當我編譯時,我只是使用:

gcc hello.c -o hello

它仍然有效..

還有另一個類似的問題,書中還說如果你有printf("%f\\n", 4); 在您的C程序中,如果編譯WITHOUT -Wall選項,則不會發出警告。 但是,我嘗試在沒有-Wall選項的情況下編譯它,但我仍然收到警告:

hello.c:6:2:警告:格式'%f'需要類型為'double'的參數,但參數2的類型為'int'[-Wformat]

為什么是這樣? 這本書說我必須提供-lm-Wall才能使我的程序編譯並得到警告但是我沒有使用它們中的任何一個但是我仍然編譯了程序並得到了警告?

謝謝!

基於一些實驗的更多信息。

考慮這個程序:

#include <stdio.h>
#include <math.h>
int main(void) {
#ifdef CONSTANT
    double x = pow(2.0, 10.0);
#else
    double expon = 10.0;
    double x = pow(2.0, expon);
#endif
    printf("x = %f\n", x);
    return 0;
}

在Ubuntu上,當我用它編譯它時

$ gcc c.c -o c

它抱怨未提及對pow引用; 添加-lm可以糾正它。

但是這個:

$ gcc -DCONSTANT c.c -o c

編譯和鏈接沒有錯誤,用常量1024.0替換pow()調用。 但是這個:

$ gcc -fno-builtin -DCONSTANT c.c -o c

再次抱怨對pow的未定義引用。

結論:只有在編譯時才能確定結果時,gcc才使用pow的內置實現。 否則它會生成對pow()函數的顯式調用,這需要與-lm鏈接。

另請注意,這取決於C庫的組織方式(庫是單獨提供的;它不是gcc的一部分)。 在Cygwin上,使用newlib而不是Ubuntu上使用的glibc ,不需要-lm選項; 顯然,數學例程是標准庫的組成部分,而不是單獨提供。 (Cygwin上的gcc仍然接受-lm選項。)

GCC提供了幾個標准庫函數作為內置函數:

GCC提供了除上述功能之外的大量內置功能。 其中一些內容用於處理異常或可變長度參數列表,因此它們可能會不時更改,因此不會在此處記錄; 我們不建議一般使用這些功能。

其余功能用於優化目的。

如果你看一下內置插件列表,你會發現pow就是其中之一。

如果將-fno-builtin添加到編譯器選項中,則應該得到您期望的鏈接器錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM