我看到了另外一個關於C代碼的問題,其代碼是gets()
, ,我評論了關於從未使用gets()
(除了 )的通常警告,當您要演示如何破解安全性時。如何讓gcc 4.7警告使用臭名昭着的gets()函數?
這次,我決定檢查我的編譯器是否發出了關於使用gets()
的 的警告。當然,我預計會。必須,對嗎?即使 你沒有指定任何警告?
想象一下,我的驚訝,當我發現,不僅編譯不 默認警告,但我甚至不能弄清楚如何使它警告!
有問題的編譯器是在Debian 4.7.2的gcc,和這裏的使用的代碼我 :
#include <stdio.h>
int main(void)
{
char s[10];
gets(s);
puts(s);
return 0;
}
試過gcc g.c
。編譯時沒有警告。運行。如果 輸入太多文本,則獲取段錯誤。
與所有標準的警告,我通常放在一個makefile嘗試:
gcc -W -Wall -Wno-long-long -Wshadow -Wlarger-than-1000 \
-Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align \
-Wconversion -Waggregate-return -Wmissing-prototypes \
-Wmissing-declarations -Wpadded -Wredundant-decls -Wnested-externs g.c
相同的結果。
試用-std=c11
。即使這並沒有產生警告,這是 很奇怪,考慮到gets()
甚至不存在於C11中。也試過 c99
。沒有警告。
那麼這裏發生了什麼?爲什麼這個非常廣泛使用的編譯器在我使用整個C語言中最不推薦使用的函數時會警告我 ?
編輯:代理下面基思·湯普森的建議,我檢查了在stdio.h
一個 棄用屬性。它不在那裏。然後我複製了 頭文件並進行了實驗。添加這兩種字符串(我 在其它頭中)的聲明結束的也產生 警告:
__attribute_deprecated__
__attribute__ ((__deprecated__))
警告:
‘gets’ is deprecated (declared at /usr/include/stdiotz.h:632) [-Wdeprecated-declarations]
總之我已經響應到目前爲止,看來我的系統上的libc版本 不包含警告,它存在於 更高版本中。這很奇怪,因爲至少從1996年起警告已存在於一些 表格中。我依稀記得libc已經至少在 處分叉一次,所以或許警告在其他分支中明顯晚於一個分支 。
我想我會在Debian郵件列表上詢問這個問題,也許 報告它是一個錯誤,這取決於我學到的東西。
編輯2:我已經看了一些源代碼。自2007年以來,glibc至少在libio/iogets.c
有警告 。 eglibc 2.13,一個我, 具有完全相同的警告代碼:
#ifdef _LIBC
link_warning (gets, "the `gets' function is dangerous and should not be used.")
#endif
我想_LIBC
當庫編譯沒有定義。爲什麼,我 不知道。我不確定_LIBC
的目的是什麼。
因此,答案似乎歸結爲「這是圖書館,無論其理由如何,以他們的智慧來看,負責它的Debian開發者 都是這樣編譯的。」我們可能永遠不知道爲什麼。
由於我使用的是oldstable,因此不會將它報告爲錯誤。如果下次升級後仍然如此,可能會帶來 。
謝謝大家,爲您提供翔實的答案!
將編譯器升級到[GCC 5](http://gcc.gnu.org/gcc-5/)並使用'gcc -Wall -Wextra -g -std = c11';你可能還需要升級你的'libc',這實際上意味着將你的Linux發行版更新到最新版本。 –
任何帖子gcc 4.6會警告有關啓動警告的'gets',如上所述。 –
@ DavidC.Rankin但是這是gcc 4.7.2,即使使用了上面提到的Basile提供的一組標誌,它也不會發出警告。 –