当我尝试用GCC编译使用gets()函数的C代码时,我得到这个警告:
(.text+0x34):警告:' gets'函数是危险的,不应该使用。
我记得这与堆栈保护和安全性有关,但我不确定确切的原因。
我如何删除这个警告,为什么使用gets()会有这样的警告?
如果gets()是如此危险,那么为什么我们不能删除它?
当我尝试用GCC编译使用gets()函数的C代码时,我得到这个警告:
(.text+0x34):警告:' gets'函数是危险的,不应该使用。
我记得这与堆栈保护和安全性有关,但我不确定确切的原因。
我如何删除这个警告,为什么使用gets()会有这样的警告?
如果gets()是如此危险,那么为什么我们不能删除它?
当前回答
我最近在comp.lang.c的一篇USENET文章中读到,gets()将从标准中删除。哦吼
你会很高兴知道 委员会刚刚投票(一致通过) 将gets()从 还有草案。
其他回答
为了安全地使用get,您必须确切地知道将要读取多少字符,以便使缓冲区足够大。只有当您确切地知道要读取哪些数据时,您才会知道这一点。
您希望使用具有签名的fgets,而不是使用gets
char* fgets(char *string, int length, FILE * stream);
(fgets,如果它读取了整行,将在字符串中留下'\n';你得自己处理。)
直到1999年的ISO C标准,gets仍然是语言的官方部分,但在2011年的标准中被正式删除。大多数C实现仍然支持它,但至少gcc会对任何使用它的代码发出警告。
如果不破坏API,就不能删除API函数。如果您这样做,许多应用程序将不再编译或运行。
这就是一篇参考文章给出的原因:
读取溢出的行 由s指向的数组结果为 未定义的行为。fgets()的使用 建议。
gets() is dangerous because it is possible for the user to crash the program by typing too much into the prompt. It can't detect the end of available memory, so if you allocate an amount of memory too small for the purpose, it can cause a seg fault and crash. Sometimes it seems very unlikely that a user will type 1000 letters into a prompt meant for a person's name, but as programmers, we need to make our programs bulletproof. (it may also be a security risk if a user can crash a system program by sending too much data).
Fgets()允许您指定从标准输入缓冲区中取出多少字符,以便它们不会溢出变量。
我想向仍然在库中包含get的C库维护者发出诚挚的邀请,“以防有人仍然依赖它”:请将您的实现替换为
char *gets(char *str)
{
strcpy(str, "Never use gets!");
return str;
}
这将有助于确保没有人仍然依赖它。谢谢你!
C语言的gets函数是危险的,是一个代价非常高昂的错误。Tony Hoare在他的演讲“Null References: The Billion Dollar Mistake”中特别提到了这一点:
http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare
整个小时都值得一看,但他从30分钟开始的评论观点在39分钟左右受到了批评。
希望这能激发你对整个演讲的兴趣,让你注意到我们如何需要语言中更正式的正确性证明,以及语言设计者如何应该为他们语言中的错误而受到指责,而不是程序员。这似乎是糟糕语言的设计者打着“程序员自由”的幌子把责任推给程序员的全部可疑原因。