C++ Boost:这个警告的原因是什么?

siv*_*udh 46 c++ boost compiler-warnings

我有一个简单的C++与Boost像这样:

#include <boost/algorithm/string.hpp>

int main()
{
  std::string latlonStr = "hello,ergr()()rg(rg)";
  boost::find_format_all(latlonStr,boost::token_finder(boost::is_any_of("(,)")),boost::const_formatter(" "));
Run Code Online (Sandbox Code Playgroud)

这很好用; 它取代了每次出现的(),用""

但是,我在编译时收到此警告:

我正在使用MSVC 2008,Boost 1.37.0.

1>Compiling...
1>mainTest.cpp
1>c:\work\minescout-feat-000\extlib\boost\algorithm\string\detail\classification.hpp(102) : warning C4996: 'std::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'
1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(2576) : see declaration of 'std::copy'
1>        c:\work\minescout-feat-000\extlib\boost\algorithm\string\classification.hpp(206) : see reference to function template instantiation 'boost::algorithm::detail::is_any_ofF<CharT>::is_any_ofF<boost::iterator_range<IteratorT>>(const RangeT &)' being compiled
1>        with
1>        [
1>            CharT=char,
1>            IteratorT=const char *,
1>            RangeT=boost::iterator_range<const char *>
1>        ]
1>        c:\work\minescout-feat-000\minescouttest\maintest.cpp(257) : see reference to function template instantiation 'boost::algorithm::detail::is_any_ofF<CharT> boost::algorithm::is_any_of<const char[4]>(RangeT (&))' being compiled
1>        with
1>        [
1>            CharT=char,
1>            RangeT=const char [4]
1>        ]
Run Code Online (Sandbox Code Playgroud)

我当然可以禁用警告

-D_SCL_SECURE_NO_WARNINGS
Run Code Online (Sandbox Code Playgroud)

但在我发现错误之前,我有点不愿意这样做,或者更重要的是,如果我的代码不正确.

jal*_*alf 52

没什么值得担心的.在MSVC的最后几个版本中,他们已经进入完全安全 - 偏执模式.std::copy与原始指针一起使用时发出此警告,因为如果使用不当,可能会导致缓冲区溢出.

它们的迭代器实现执行边界检查以确保不会发生这种情况,从而导致显着的性能成本.

所以随意忽略警告.这并不意味着您的代码有任何问题.它只是说,如果你的代码有问题,那么坏事就会发生.发出警告是一件奇怪的事情.;)

  • 这个警告让我疯了,就像一杯热咖啡的内容一样"警告". (23认同)
  • 关于它的最糟糕的事情是没有理智的"修复".发布大多数警告是因为有更好的,更不容易出错的方式来实现同样的事情.它们可以*固定*.你应该怎么做这个?如果您有一个原始C数组,并且需要将数据复制到其中或从中复制数据,则指针是唯一可用的迭代器类型.到目前为止,std :: copy是最安全的选项.或者他们是否建议我们回去写循环来实现同样的目的? (9认同)
  • 如[this](http://stackoverflow.com/a/3329714/1704355)中所述,回答类似(重复?)的问题,忽略Visual Studio中的警告,转到`Project properties`->`C++` - >`Advanced`->`禁用特定警告`并输入`4996`. (3认同)

Biz*_*rck 25

您还可以在特定标头中禁用此警告:

#if defined(_MSC_VER) && _MSC_VER >= 1400 
#pragma warning(push) 
#pragma warning(disable:4996) 
#endif 

/* your code */ 

#if defined(_MSC_VER) && _MSC_VER >= 1400 
#pragma warning(pop) 
#endif 
Run Code Online (Sandbox Code Playgroud)

  • 不必要; 例如,头<xutility>,其中包含标记为已弃用的std :: copy的实现,其用法产生此警告,在最顶部有#pragma warning(push,3),导致编译器覆盖您的警告设置3级默认值. (9认同)

Blu*_*ron 19

如果您对禁用此错误感到安全:

  • 转到C++项目的属性
  • 展开"C/C++"
  • 突出显示"命令行"
  • 在"其他选项"下,将以下内容添加到该框中可能包含的任何文本

"-D_SCL_SECURE_NO_WARNINGS"

  • 更清洁:在预处理器定义下添加"_SCL_SECURE_NO_WARNINGS"(也在"C/C++"类别下) (6认同)
  • 请记住,即使您确定当前的代码是安全的,您最终也可能编写一些不安全的代码并且不会被警告. (2认同)
  • 是的,但在这种情况下,就像是说:"带上你的雨伞,今天可能会下雨." 被告知每天都没有用,因为它没有提供任何信息,即使在香农意义上也是如此.最终,它会下雨,你会被警告带上你的雨伞.如果警告是,"气象站预测今天下雨80%的机会,拿你的伞,"然后这是有用的,因为它提供信息. (2认同)

fbr*_*eto 8

警告来自Visual Studio从MSVC 8.0开始引入的非标准"安全"库检查.微软已经确定了"具有潜在危险"的API,并且已经注意到了阻止其使用的警告.虽然技术上可以以不安全的方式调用std :: copy,但是1)接收此警告并不意味着你这样做,并且2)正常情况下使用std :: copy并不危险.