为什么C11标准没有';是否删除不安全的strcat()、strcpy()函数?

为什么C11标准没有';是否删除不安全的strcat()、strcpy()函数?,c,strcpy,c11,strcat,C,Strcpy,C11,Strcat,C11&C++14标准删除了本质上不安全的函数gets(),因为它不执行边界检查会导致缓冲区溢出,从而导致安全问题。那么为什么C11标准不删除strcat()&strcpy()函数呢strcat()函数不检查第二个字符串是否适合第一个数组strcpy()函数也不包含检查目标数组边界的规定。如果源数组的字符数超过目标数组所能容纳的字符数,该怎么办?程序很可能在运行时崩溃 那么,如果这两个不安全的函数完全从语言中移除,那不是很好吗?为什么它们仍然存在?原因是什么?只有像strncat()、strnc

C11
&
C++14
标准删除了本质上不安全的函数
gets()
,因为它不执行边界检查会导致缓冲区溢出,从而导致安全问题。那么为什么
C11
标准不删除
strcat()
&
strcpy()
函数呢
strcat()
函数不检查第二个字符串是否适合第一个数组
strcpy()
函数也不包含检查目标数组边界的规定。如果源数组的字符数超过目标数组所能容纳的字符数,该怎么办?程序很可能在运行时崩溃


那么,如果这两个不安全的函数完全从语言中移除,那不是很好吗?为什么它们仍然存在?原因是什么?只有像
strncat()、strncpy()这样的函数不是很好吗?如果我没有错,微软C&C++编译器提供了这些函数的安全版本<代码> StrucIyx()、StrutAX()< /C>。那么为什么其他C编译器没有正式实现它们以提供安全性呢?

您所说的是会导致未定义行为的场景

比方说

char a[3] = "string";
for(i=0;i<5;i++)
printf("%c\n",a[i]);
chara[3]=“string”;
for(i=0;i
gets()
本质上是不安全的,因为通常,如果在
stdin
上接收到太多数据,它会溢出目标。这:

char s[MANY];
gets(s);
如果输入的字符超过
字符,则将导致未定义的行为,并且程序通常无法阻止它

strcpy()
strcat()
可以完全安全地使用,因为只有当源字符串太长而无法包含在目标数组中时,它们才能溢出目标。源字符串包含在程序本身控制的数组对象中,而不是任何外部输入。例如:

char s[100];
strcpy(s, "hello");
strcat(s, ", ");
strcat(s, "world");
除非修改程序本身,否则不可能溢出

strncat()
可以用作
strcat()
的更安全版本——只要正确指定第三个参数。
strncat()有一个问题
它只为您提供了一种处理目标数组中空间不足的情况的方法:它默默地截断字符串。有时这可能是您想要的,但有时您可能希望检测溢出并采取一些措施


至于
strncpy()
,它不仅仅是
strcpy()的更安全版本
。这本身并不危险,但如果不十分小心,您可以很容易地离开目标数组而不使用终止的
'\0'
空字符,从而在下次将其传递给需要字符串指针的函数时导致未定义的行为。实际上,.

strcpy
strcat
gets
gets
的问题是,它用于读取输入,因此程序员无法控制是否会出现缓冲区溢出


C99 Rational将
strncpy
解释为:

§7.21.2.4
strncpy
功能
strncpy
最初被引入到C库中,用于处理目录项等结构中的固定长度名称字段。这些字段的使用方式与字符串不同:最大长度字段不需要尾随null,将较短的5个名称的尾随字节设置为null可确保有效的字段压缩arisons.
strncpy
从起源上讲不是一个“有界的
strcpy
,”
,委员会倾向于承认现有实践,而不是改变功能以更好地适应这种使用

当删除一个函数时,标准必须考虑的主要问题之一是它能中断多少代码,有多少人(程序员、库作者、编译器供应商等)会对这种改变感到恼怒(或将反对)。

gets()
已被LSB(Linux标准库)弃用。POSIX-2008使其过时,而且历史上一直认为
gets()
是一个非常糟糕的函数,并且一直强烈反对在任何代码中使用。几乎每个C程序员都知道使用
gets()是非常危险的
。因此,删除它破坏任何生产代码的可能性非常小,它不是,不存在。因此,委员会很容易从C11中删除
get()

但是,strcpy、strcat等的情况并非如此。它们可以安全地使用,并且仍被许多程序员在新代码中使用。虽然它们可能会出现缓冲区溢出,但主要是程序员的控制,而
get()
则不是

可以使用
snprintf
代替
strcpy
strcat
,但在以下简单情况下似乎没有意义:

char buf[256];
strcpy(buf, "hello");
(如果
buf
是指针,则需要跟踪分配大小,以便在
snprintf
中使用)

因为作为一名程序员,我知道,以上这些都是非常安全的。更重要的是,很多遗留代码都会被破坏。基本上,没有任何强大的参数可以用来删除strcpy等函数,因为它们可以安全地使用。

  • 谬论1:strcpy()是不安全的,它的工作原理让一位资深C程序员大吃一惊
  • 谬论2:strncpy()是安全的
  • 误解3:strncpy()是strcpy()的一个更安全的版本
  • 误解4:微软是C语言使用的权威,知道他们在说什么
strcat()
strcpy()

还要注意的是,
strncpy
。它用于一种古老版本的Unix中使用的晦涩、过时的字符串格式。
strncpy
实际上是(),与
strcpy
不同,因为似乎很少有程序员能够使用前者而不产生