C4996(函数unsafe)警告strcpy但不是memcpy

Atu*_*tul 4 c visual-studio-2010

我在VS2010中编写代码,我碰巧在编译后看到编译器为strcpy和sprintf调用提供了C4996警告("此函数或变量可能不安全").

但是,我无法获得memcpy的类似警告(可能在代码中有更多类似的'不安全'函数调用)

int _tmain(int argc, _TCHAR* argv[])
{
    char buf1[100], buf2[100];
    strcpy (buf1, buf2); // Warning C4996 displayed here asking to use strcpy_s instead
    memcpy (buf1, buf2, 100); // No warning here asking to use memcpy_s
    memcpy_s(buf1, 100, buf2, 100);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么会这样?如何在代码中为所有可能的不安全呼叫打开C4996警告?

Lun*_*din 18

通常,要编译C代码,您需要一个符合C的编译器.Visual Studio是一个不合格的C++编译器.

您收到警告,因为Visual Studio很糟糕.看到这个.

只要您使用Microsoft认为过时的功能,就会出现C4996.显然,微软决定他们应该决定C语言的未来,而不是ISO C工作组.因此,您会得到错误的警告以获得完美的代码.编译器就是问题所在.

strcpy()函数没有任何问题,这是一个神话.这个功能已经存在了大约30 - 40年,每一点都有适当的记录.因此,即使对于初学者C程序员来说,该功能的功能和功能也不应该让人感到惊讶.

strcpy做什么和不做什么:

  • 它将以null结尾的字符串复制到另一个内存位置.
  • 它对错误处理不承担任何责任.
  • 它不修复调用者应用程序中的错误.
  • 它对教育C程序员没有任何责任.

由于上面的最后一句话,在调用strcpy之前必须知道以下内容:

  • 如果将未知长度的字符串传递给strcpy,而不事先检查其长度,则调用者应用程序中存在错误.
  • 如果传递一些不以数据结尾的数据,则\0调用者应用程序中存在错误.
  • 如果将两个指针传递给strcpy(),指向重叠的内存位置,则调用未定义的行为.这意味着您在调用者应用程序中有一个错误.

例如,在您发布的代码中,您从未初始化数组,因此您的程序可能会崩溃并烧毁.该bug与strcpy()函数没有丝毫关系,并且不会通过替换strcpy()来解决其他问题.


Sim*_*ter 6

strcpy如果NUL缺少终止符,则是不安全的,因为它可能会复制更多的字符,而不适合目标区域。使用memcpy,复制的字节数是固定的。

memcpy_s函数实际上使程序员更容易出错:您传递了两个长度,并且使用了两者中的较小者,而您得到的只是一个错误代码,可以毫不费力地将其忽略。调用memcpy需要填写size参数,这应该使程序员考虑要传递的内容。

  • 如果向其传递垃圾参数,则任何C函数都是不安全的。 (11认同)