看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《k03004748549 (蜆)》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) : GCC (Ubuntu 4.8.2-19ubuntu1) : 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) : 只有 -lm : 問題(Question): : 大家好...我最近才剛接觸C : 這邊問的感覺應該是小問題,不過google都查不到... : 還請各位鞭小力點 : 最近在看一段code,其年代久遠(約1990) : 可能是規範與現今有差異,或是當時平台不同(好像最早是在sparc上run的) : code裏面常有一些疏漏 : 例如: : 2. 使用了malloc、exit、strlen卻沒有 #include <stdlib.h> : 同樣的有warning出現 : warning: incompatible implicit declaration of built-in : function ‘strlen’ [enabled by default] : 這邊我也是很好奇不去include到底compiler會做什麼事 : 因為程式仍然可以執行,而且某些程式(很少,大約一兩個) : 在我 #include <stdlib.h>之後 : 反而會出現 segmentation fault,讓我感到很疑惑 : 還煩請各位指點迷津,謝謝 猜不到怎麼出現 segmentation fault 的, 先提供引起這個錯誤的那一段程式碼再看看吧。 來說說這個 warning,首先你必須知道: C90 標準允許使用一個函數時,不需要提供原型宣告,因為編譯器會 假定該函數的返回型態是 int。至於堆疊平衡的需求,因為這一類函數 的堆疊是由 caller 負責清理,所以沒有原型宣告,還是能正確維持平衡。 C99 不允許上述行為,C++ 也是。 gcc 比 VC 在這方面還要雞婆,它的編譯器會事先儲存 C 標準函數的 原型宣告資訊,而且預設就會使用這部份資訊,除非你在編譯時,使用 這個參數: -fno-builtin 舉例來說,當有以下程式碼時: #include <stdio.h> #include <stdlib.h> int main() { printf("%f\n", sqrt(16.0)); return 0; } gcc 使用 C90 標準編譯: gcc -std=c90 ss.c 會出現警告訊息: warning: incompatible implicit declaration of built-in function 'sqrt' [enabled by default] printf("%f\n", sqrt(16.0)); ^ 意思是,在隱式宣告下,其原型資訊為 int sqrt(double); 但是這個內建函數的原型,已查出是 double sqrt (double x); 因此兩者不相容 (incompatible),而 gcc 將會主動使用內建的原型宣告。 主要是警告 VC 使用者,這裡不會跟 VC 一樣,當成 int sqrt(double) 來用。 ※ 上面的程式執行結果是:4.000000 如果改成這樣編譯:gcc -std=c90 -fno-builtin ss.c 則不會有警告訊息,而且程式執行結果會跟 VC 編譯出來的一樣,都是 0.000000。 原因並不難理解,因為 sqrt 函數把返回值放在專門存放 double 的地方,可是 編譯器以為他的返回值是 int,所以跑去另一個地點取值,最後取到錯誤的資訊。 附帶一提,如果是 C++ 編譯器,會直接編譯錯誤,如果是 C99 編譯的話: gcc -std=c99 -fno-builtin ss.c ss.c: In function 'main': ss.c:5:3: warning: implicit declaration of function 'sqrt' [-Wimplicit-function-declaration] printf("%f\n", sqrt(16.0)); ^ 這個錯誤訊息,是由於 C99 標準不想像 C90 這樣,隱含的把函數返回值當成 int, 但是又不想害以前的 C90 使用者編譯失敗,所以只提出警告。 -- 要報仇就快 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 124.8.138.250 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1416824909.A.E7F.html
k03004748549: 謝謝p大的詳細解說 11/24 19:25
k03004748549: 還有剛剛man gcc才發現預設 -std=gnu90 11/24 19:25
k03004748549: 加上這篇就全都串得起來了 感謝 11/24 19:26
lc85301: (worship) 11/25 13:27
autoupdate: 受益良多 3Q 12/13 20:42