为什么我会收到_SCL_SECURE_NO_WARNINGS消息

[原文发表地址] 为什么我会收到_SCL_SECURE_NO_WARNINGS消息

[原文发表时间] 2017/05/35

最近一个C++开发人员问为什么他们会得到这个代码的诊断消息

如果你在调试模式下编译此文件,你将收到以下消息:

xutility(2350,1): warning C4996:

'std::copy::_Unchecked_iterators::_Deprecate': Call to 'std::copy' 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' _DEPRECATE_UNCHECKED(copy, _Dest); ^ xutility(2350):

note: see declaration of 'std::copy::_Unchecked_iterators::_Deprecate'

_DEPRECATE_UNCHECKED(copy, _Dest); .\test.cpp(4): note: see reference to

function template instantiation '_OutIt std::copy<const

char,char*>(_InIt,_InIt,_OutIt)> ' being compiled with [ _OutIt=char *,

_InIt=const char * ] std::copy(src, src + 42, dest);

这是由于STL的迭代器调试支持引起的。如果您打开调试(用/MTd或者/MDd)STL会为您检查结果范围的大小,如果您只给我们一个简单的指针,std::copy将无法确定范围的结尾在哪里。你可以通过很多方式告诉STL范围的结尾:

有可能的话,你可以通过std::copy一个简单的数组。如果你从数组开始,我们将会看到数组的范围,并且进行恰当的边界检查。

  1. 几种标准库算法在C++14中受到“双范围”版本。如果你使用双范围版本,则第二个范围已经提供必要的边界检查:
  2. 你可以用标准的容器回到目的地,如字符串或向量。如果_ITERATOR_DEBUG_LEVEL不为0,迭代器就有足够的信息知道它在哪里结束并且提供适当的边界检查。
  3. 你可以使用stdext::make_checked_array_iterator 创建一个知道目标大小的迭代器。
  4. 你可以决定在该区域允许存在这些代码隐患,并通过项目中或者在包含STL的头文件之前定义_SCL_SECURE_NO_WARNINGS来规避这些隐患,,有了这些设置,尽管STL仍会在必要的地方进行边界检查,但是当它不能这样做时将不再发出警告。

您有想要写给我们的问题吗?关于这个帖子或者你想要看到的内容的其他反馈(像某个特定场景的C++教程)?在评论里写下来或者发邮件给Eric(ebattali@microsoft.com)。感谢!