2009-11-23 85 views
8

我有以下的C代碼:爲什麼gcc報告「函數的隱式聲明」round'「?

#include <math.h> 

int main(int argc, char ** argv) 
{ 
    double mydouble = 100.0; 
    double whatever = round(mydouble); 

    return (int) whatever; 
} 

當我編譯,我得到了警告:

round_test.c: In function ‘main’: 
round_test.c:6: warning: implicit declaration of function ‘round’ 
round_test.c:6: warning: incompatible implicit declaration of built-in function ‘round’ 

我生疏C,但我認爲的#include帶來的聲明對於round()進入範圍。我檢查了我的ANSI標準(C99是我唯一的副本),它證實了round()函數存在於math.h頭文件中。我在這裏錯過了什麼?

編輯:編譯器是Ubuntu上的GCC 4.3.2(intrepid,IIRC)。運行gcc -E給出:

$ gcc -E round_test.c | grep round 
# 1 "round_test.c" 
# 1 "round_test.c" 
# 2 "round_test.c" 2 
    double whatever = round(mydouble); 

所以在頭文件中顯然沒有找到定義。

回答

17

我看到你使用的是gcc。

默認情況下,gcc使用類似於C89的標準。您可能要「逼」它使用C99標準

gcc -std=c99 -pedantic ... 

報價從GCC Manual

默認情況下(它遵循的部件),GCC提供了一些 擴展的C語言上極少出現與標準C 衝突的情況。請參閱C 語言族的擴展。使用上面列出的-std 選項將禁用 這些擴展,它們與選擇的C標準版本衝突 。 您也可以選擇具有-std = gnu89(對於帶有GNU 擴展的C89)或-std = gnu99(對於具有GNU擴展的C99 )的擴展 版本的C語言顯式地 。默認,如果 沒有C語言方言選項 給出,是-std = gnu89;當C99支持完成時,在將來的某些版本 中,這會將 更改爲-std = gnu99。作爲C99 標準一部分的一些功能被接受爲 C89模式的擴展。

+1

謝謝,-std = c99似乎解決了它。我沒有意識到round()是C99的補充(當然,我所有的參考都是C99,而忽略了這一點) – 2009-11-23 15:32:55

+0

(驚訝的樣子)round()真的是C99的補充嗎? – 2009-11-23 15:43:56

+0

對,C89沒有描述'round()'函數(當然編譯器可以提供它作爲擴展)。 – pmg 2009-11-23 15:50:48

3

你的gcc安裝,系統頭文件或編譯選項必須有錯誤。

嘗試使用-E編譯。這將向您顯示預處理器輸出的內容 - 包括哪些頭文件包含在內以及內容中。在我的Ubuntu Linux系統上,它大約有1000行輸出,其中包括:

extern double round (double __x) __attribute__ ((__nothrow__)) __attribute__ ((__const__)); 
+0

我在Ubuntu 9.10(Karmic)。這裏'#include '加載/usr/include/math.h加載包含聲明的/usr/include/bits/mathcalls.h。 – 2009-11-23 15:41:30

0

您輸入的代碼在MacOS X 10.5.8上用GCC 4.0.1編譯乾淨。如果用選項'-Wall -Wextra'激勵,它會抱怨未使用的參數argc和argv - 不重要。

你在機器上看過<math.h>嗎?

您是否嘗試過使用'-stc = c99'等選項?

3

你需要告訴你想要C99 GCC,而且要在libm中鏈接:

gcc -std=c99 -lm round_test.c 
-2

你需要用數學庫鏈接。所以當你編譯時,一定要添加-lm標誌。

+1

感謝您的輸入,但這是一個編譯問題,而不是鏈接問題。我意識到我遺漏了我的編譯器命令(我的壞),但我正在用gcc -c編譯。 – 2009-11-23 15:57:23

0

C99是答案,但整個故事稍微複雜一點。我一直在玩這個遊戲的原因是,我試圖編譯一個爲Windows編寫的庫,它有自己的round()的「優化」定義。我得到一個鏈接器錯誤告訴我,定義與內置衝突,所以我刪除了定義(和聲明)。一旦我做完了,我開始得到「隱式聲明錯誤」。

似乎默認的編譯模式(沒有-std = c99標誌)既不符合C89也不符合C99:如果它符合C89,則應該能夠提供round()的自定義定義而不會發生衝突,並且如果它符合C99的聲明應該在math.h中。

+1

默認模式是'-std = gnu89' :) – pmg 2009-11-23 15:56:47

相關問題