gets()函数已被正式弃用吗?

5
根据C++11的最新草案,C ++是指ISO / IEC 9899:1999 / Cor.3:2007(E)以获取C库函数的定义(每§1.2 [intro.refs] / 1)。
基于C99 TC3的最新草案gets函数已过时,不推荐使用。(每§7.26.9 / 2)
我可以放心地说,在C和C ++中,gets()都已过时了吗?

9
重要吗?不管怎样你都不应该使用它。 - Carl Norum
3
这段话的意思是:“手册上说,永远不要使用gets()。因为在未知数据大小的情况下无法确定gets()函数将读取多少个字符,并且这个函数会继续存储超出缓冲区结尾的字符,所以使用它非常危险,甚至可能被用来破坏计算机安全。建议使用fgets()代替gets()。所以,我建议无论其官方状态如何都不要使用gets()。” - Brian Roach
2
gets() 应该仅用于教新手程序员有关缓冲区溢出的知识。 - fbafelipe
我不使用它,但在争论中,“危险”听起来并不像“已弃用”那样强烈。许多事情都是危险的。 - Cubbi
5
@Cubbi:很多被错误标记为“危险”的东西既有正确的用法,也有不正确的用法,称其为“危险”的人基于可能会有人以不正确的方式使用它而做出了自己的判断。另一方面,“gets”函数实质上没有正确的用法;任何对它的使用都会导致程序出错。 - R.. GitHub STOP HELPING ICE
它引发了一个链接器警告。你上次见到一个不是真正危险的链接器警告是什么时候。 - Joshua
5个回答

4

“Deprecated”意味着你不应该使用它,而且将来可能会被移除。由于两个标准都说它已经被弃用了,这意味着它已经正式被弃用了。


3
这有关紧要吗?只有当您完全掌控 stdin的文件内容且已附加到该文件时,您才能使用 gets 。这种情况几乎不可能实现,特别是在多进程系统上,其他进程可能会异步修改文件,导致程序出现未定义行为。因此,从实际目的来看,任何使用 gets 的程序都具有未定义的行为(即存在可能导致其出现未定义行为的输入/环境条件),尤其是如果您的程序拥有高于数据提供者的特权,则可能导致权限被破坏。 编辑:好的,下面是我能想到的一个安全使用 gets 的例子。
if (feof(stdin)) gets(buf);

当然,一些有缺陷的实现(可能包括glibc..?)允许在流的EOF指示器已经设置时进行读取,因此...

有人可能会认为输入是他们的合同的一部分,但我想GIGO方法也早已过时了。 - Cubbi
1
@Cubbi:我严格区分GIGO和GIUBO。 - R.. GitHub STOP HELPING ICE
哈哈,你给出的“一次安全使用”真的有任何用途吗?如果你知道stdin已经到达了EOF,为什么还要尝试从它获取输入呢? - flarn2006
@flarn2006:不,这主要是对read-past-eof bug的便宜攻击。 :-) - R.. GitHub STOP HELPING ICE

1
即便从库中删除 gets() 后可能会导致代码出错,但相比此前,删除它后代码的错误程度会降低。我认为编译器供应商可能需要将其包含在“完全符合标准”的模式中,但安全地使用它的情况是极少的,因此将其排除在“正常”构建之外可能是合理的选择。

0

好吧,它在C11标准中完全被移除了,所以我认为答案是肯定的。


0

要等一段时间才能在所有地方实现C++11。

此外,大多数编译器甚至还没有完全支持C99。

例如,微软的编译器就不支持。

因此,在C和C++中都没有被弃用。


4
这句话的意思是,“长久以来,所有理智的程序员都已经不再使用它了。由于向后兼容的原因,它仍然存在于系统中。但这并不意味着你必须使用它;事实上,你不应该使用它。至于微软不支持C99标准,我认为这足以成为淘汰微软编译器的理由。” - Jonathan Leffler
@Jonathan:除了一个小细节,Visual-C++是一个*C ++*编译器;它没有义务完全支持C99(我认为随着C ++ 11的到来,它会这样做)。 - Xeo
弃用并不一定意味着现代编译器不支持某些功能。实际上,向后兼容通常被视为一件好事。它所意味的是程序员不应该在新代码中使用已经被弃用的内容,并且他们被鼓励从旧代码中删除它。 - flarn2006

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接