在用VS2013测试string::copy()时发生编译错误,错误提示如下:
错误 2 error C4996: 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::copy':
Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct.
To disable this warning,use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
该提示信息本来是表达了“string::copy()带有可能不安全的参数的函数调用 - 此调用依赖于调用者来检查传递的值是否正确”的警告信息,但在VS2013直接报错,就是因为string::copy()函数不安全,copy函数原型如下:
size_type copy(char *buffer, size_type num, size_type index );
因为如果buffer的内存大小比num小,那么就会溢出,导致崩溃(而不是异常)。如果要消除这种警告/“错误”(编译器认为错误,按理来说只是一种警告),就需要按照提示:“To disable this warning, use -D_SCL_SECURE_NO_WARNINGS”添加参数“_SCL_SECURE_NO_WARNINGS”(SCL安全无警告,S代表Safety 安全、C代表Check检查、L代表List清单)到预处理器定义中,不警告这种不安全的操作方式,方法如下:
项目->属性->配置属性->C/C++->预处理器->预处理器定义(末尾加上“_SCL_SECURE_NO_WARNINGS”即可(注意分号隔开))(如下图):
除了上述方法之外,我们看到在错误提示中“error C4996”,所以我们还可以用#pragma预处理来消除警告,如下:
#pragma warning(disable:4996)
/*忽略4996警告(错误)即string::copy()的不安全警告*/
在有些时候(大多数情况),早期的不安全的函数在VS新的版本中会有安全版本,如scanf()的安全版本scanf_s(),fopen()的安全版本fopen_s()等等,我们首选的是安全版本,但是这里的copy()没有这种安全的改进,所以我们只能采用消除/忽略警告的方式来处理。