C++ 'strcpy' 发出警告 (C4996)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4012222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:17:03  来源:igfitidea点击:

C++ 'strcpy' gives a Warning (C4996)

c++visual-c++

提问by Sudantha

I am getting this warning but all functions working properly .

我收到此警告,但所有功能都正常工作。

what does this really means?

这到底是什么意思?

'strcpy': This function or variable may be unsafe. 
Consider using strcpy_s instead. To disable deprecation, 
use _CRT_SECURE_NO_WARNINGS. See online help for details.

回答by Cratylus

This function (strcpy) is considered unsafe due to the fact that there is no bounds checking and can lead to buffer overflow. (Actually strcpy is infamous for overflow exploits and all programmers avoid it-or at least should avoid it). The advice is to use a safe function which takes into account the size of the destination buffer to avoid overflow. You could also use strncpy (BUT with caution!). There is no problem with your code, i.e. the functions will run as you say but try giving as input a buffer that is larger than the destination buffer. The function will overflow the destination buffer. Check this also link text

此函数 (strcpy) 被认为是不安全的,因为没有边界检查,并且可能导致缓冲区溢出。(实际上 strcpy 因溢出漏洞而臭名昭著,所有程序员都避免使用它——或者至少应该避免它)。建议是使用考虑目标缓冲区大小的安全函数以避免溢出。您也可以使用 strncpy (但要小心!)。您的代码没有问题,即函数将按您说的方式运行,但尝试提供一个大于目标缓冲区的缓冲区作为输入。该函数将溢出目标缓冲区。检查这也链接文本

回答by Montdidier

While strcpy is a common string function, it has a history of being the source of many bugs and security holes in software (due to the ease of buffer overflows).

虽然 strcpy 是一个常见的字符串函数,但它一直是软件中许多错误和安全漏洞的来源(由于缓冲区溢出很容易)。

Microsoft, in an effort to promote safer coding in C and C++ has provided a suite of replacement functions for the dangerous string methods. Typically they have the original name postpended with _s. Hence the Microsoft secure version of strcpy is strcpy_s as recommended in the warning. Note this a Microsoft specific feature, it's not ubiquitious.

微软为了促进更安全的 C 和 C++ 编码,为危险的字符串方法提供了一套替换函数。通常,它们的原始名称后跟 _s。因此,根据警告中的建议,strcpy 的 Microsoft 安全版本是 strcpy_s。请注意,这是 Microsoft 的特定功能,它并非无处不在。

You've got a few options.

你有几个选择。

  1. DEFINE _CRT_SECURE_NO_WARNINGS if you don't want to care about it, leaving the possibility of the security issues in your software.
  2. Replace your string functions with the secure ones, leaving your software less portable as a consequence
  3. Wrap the secure string functions and use the wrappers everywhere, providing enhanced security on Windows platforms, and falling back to the traditional versions on other platforms. The wrapper functions could be via a MACRO or compiled functions.
  1. DEFINE _CRT_SECURE_NO_WARNINGS 如果你不想关心它,就会在你的软件中留下安全问题的可能性。
  2. 用安全的函数替换您的字符串函数,从而使您的软件可移植性降低
  3. 包装安全字符串函数并在任何地方使用包装器,在 Windows 平台上提供增强的安全性,并在其他平台上回退到传统版本。包装函数可以通过宏或编译函数。

I typically do #3.

我通常做#3。

回答by Konrad Rudolph

Since you're programming C++, the correct solution is to ban C-style char*strings from your code where possible, and replace them by std::string(or another appropriate string type).

由于您正在对 C++ 进行编程,因此正确的解决方案是char*在可能的情况下从您的代码中禁止 C 样式的字符串,并将它们替换为std::string(或其他适当的字符串类型)。

Do notuse functions such as strcpyor strcpy_sor strncpy. Use the copy constructor or assignment operator of the stringclass. Or if you really need to copy buffers, use std::copy.

千万不能使用的功能,如strcpystrcpy_sstrncpy。使用类的复制构造函数或赋值运算符string。或者,如果您确实需要复制缓冲区,请使用std::copy.

回答by sharptooth

Since VC++ 8 strcpy()and a huge set of other functions are considered to be unsafesince they don't have bounds checking and can lead to a buffer overrun if misused.

由于 VC++ 8strcpy()和大量其他函数被认为是不安全的,因为它们没有边界检查,如果误用可能会导致缓冲区溢出。

You have two options:

您有两个选择:

  • if you're unsure - do what VC++ says and use "safe" functions. They will trigger an error handler that will terminate your program if something goes wrong.
  • if you know what you're doing - you know that no overrun will ever occur and all edge cases are handled by your code - define _CRT_SECURE_NO_WARNINGSprior to including CRT headers and this will make the warning go away.
  • 如果您不确定 - 执行 VC++ 所说的并使用“安全”功能。如果出现问题,它们将触发一个错误处理程序,该处理程序将终止您的程序。
  • 如果您知道自己在做什么 - 您知道永远不会发生溢出并且所有边缘情况都由您的代码处理 -_CRT_SECURE_NO_WARNINGS在包含 CRT 标头之前定义,这将使警告消失。

回答by Vladski

That warning is basically informing you that strcpy is deprecated, because copying a string until \0can easily lead to nasty problems (buffer overruns). The reason strcpy is still there and works is that it is part of the standard library legacy, but you should really consider using str*_s or strn* functions (which don't exclusively rely on finding the terminating \0).

该警告基本上是在通知您 strcpy 已被弃用,因为复制字符串直到\0很容易导致令人讨厌的问题(缓冲区溢出)。strcpy 仍然存在并且有效的原因是它是标准库遗留的一部分,但您真的应该考虑使用 str*_s 或 strn* 函数(它们不完全依赖于查找终止\0)。

Since buffer overruns are linked not only to security problems, but also to bugs which are relatively difficult to trace and fix, using plain vanilla str* functions is not only generally frowned upon, but can lead to people rejecting your code as inherently unsafe.

由于缓冲区溢出不仅与安全问题有关,而且与相对难以跟踪和修复的错误有关,因此使用普通的 str* 函数不仅通常不受欢迎,而且可能导致人们拒绝您的代码,因为您的代码本质上是不安全的。

More details: http://www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html

更多详情:http: //www.safercode.com/blog/2008/11/04/unsafe-functions-in-c-and-their-safer-replacements-strings-part-i.html

回答by Vladski

There is actualy a way to avoid this warning, still use strcpy, and be safe:

实际上有一种方法可以避免这个警告,仍然使用 strcpy,并且是安全的:

You can enable the secure template overloads. They will (if possible) deduce the lengths of the buffers used by capturing them with templated overloads. It's a mystery to me why this is not enabled by default in Visual C++.

您可以启用安全模板重载。他们将(如果可能)通过使用模板化重载捕获它们来推断使用的缓冲区的长度。为什么在 Visual C++ 中默认情况下没有启用这对我来说是个谜。

回答by Kool Wagh

#pragma warning(disable: 4996)

use above code in the first line of your code.

在代码的第一行使用上面的代码。

回答by brett bazant

If you have looked at the pros and cons of using C++ purist technique vs. not worrying because you 'know' your strings will be zero terminated, then you can also disable the warning in msvc, this sort of thing:

如果您已经查看了使用 C++ 纯粹技术与不用担心的利弊,因为您“知道”您的字符串将以零结尾,那么您还可以在 msvc 中禁用警告,这类事情:

#ifdef _MSC_VER
  // 4231: nonstandard extension used : 'extern' before template explicit instantiation
  // 4250: dominance
  // 4251: member needs to have dll-interface
  // 4275: base needs to have dll-interface
  // 4660: explicitly instantiating a class that's already implicitly instantiated
  // 4661: no suitable definition provided for explicit template instantiation request
  // 4786: identifer was truncated in debug information
  // 4355: 'this' : used in base member initializer list
  // 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation
#   pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355 4910)
#endif

回答by raidsan

use Secure Template Overloadsor define wrapper functionsnot work for dynamically allocated buffers, so this attempt is futile.
Either modify source to use secure replacement, or just ignore it.

使用安全模板重载定义包装函数不适用于动态分配的缓冲区,因此这种尝试是徒劳的。
修改源以使用安全替换,或者只是忽略它。

if the codes are writing by yourself, you had better change such strcpy to strcpy_s etc. if the modules are imported from trusted soures, you may choose to ignore the warning.

如果代码是自己写的,最好把strcpy改成strcpy_s等。如果模块是从可信源导入的,可以选择忽略警告。

ignore method 1: project globle scope: add _CRT_SECURE_NO_WARNINGS
ignore method 2: ignore particular module: if only one or two of them, then you could simplely forbit warning for these modules when include them:

忽略方法 1:项目全局范围:添加 _CRT_SECURE_NO_WARNINGS
忽略方法 2:忽略特定模块:如果只有其中一两个,那么您可以在包含它们时简单地禁止对这些模块发出警告:

#pragma warning(push)
#pragma warning(disable: 4996)
#include <sapi.h>  //legacy module
#include <sphelper.h> //legacy module
#pragma warning(pop)