【问题标题】:C++ Boost: what's the cause of this warning?C++ Boost:这个警告的原因是什么?
【发布时间】:2010-11-21 00:55:21
【问题描述】:

我有一个带有 Boost 的简单 C++,如下所示:

#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(" "));

这很好用;它将 ( ) 的每次出现替换为 " "

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

我使用的是 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>        ]

我当然可以使用

禁用警告
-D_SCL_SECURE_NO_WARNINGS

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

【问题讨论】:

    标签: c++ boost compiler-warnings


    【解决方案1】:

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

    他们的迭代器实现会执行边界检查以确保不会发生这种情况,但会付出巨大的性能代价。

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

    【讨论】:

    • 这个警告让我抓狂,就像是关于一杯热咖啡的“警告”。
    • 最糟糕的是没有理智的“修复”。发出大多数警告是因为有一种更好、更不容易出错的方法来实现相同的目标。它们可以是固定的。你应该怎么处理这个?如果您有一个原始 C 数组,并且需要向其中复制数据或从中复制数据,则指针是唯一可用的迭代器类型。 std::copy 是迄今为止最好的最安全的选择。还是他们建议我们重新编写 for 循环来实现相同的目标?
    • 我打赌 100 次代表它会在第一个 SP 中与另一个“他们不测试他们发布的内容吗?”问题...
    • 具有讽刺意味的是,一种解决方法是改用 memcpy。从安全的角度来看,这可能更糟,但编译器喜欢它。
    • this 对类似(重复?)问题的回答中所述,要忽略 Visual Studio 中的警告,请转到 Project properties->C++->Advanced->@ 987654326@ 并输入4996
    【解决方案2】:

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

    #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 
    

    【讨论】:

    • 不一定;例如,标头 包含标记为已弃用的 std::copy 的实现,并且其使用会产生此警告,在最顶部有 #pragma warning(push,3),导致编译器覆盖您的警告设置3 级默认设置。
    【解决方案3】:

    如果您对禁用此错误感到放心:

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

    “-D_SCL_SECURE_NO_WARNINGS”

    【讨论】:

    • 请记住,即使您确定您当前的代码是安全的,您最终也可能会编写一些不安全的代码并且您不会收到警告。
    • 是的,但在这种情况下,它就像是在说:“带上你的伞,今天可能会下雨。”被告知每天都没有用,因为它没有提供任何信息,即使在香农意义上也是如此。最终,会下雨,你会被警告带上你的雨伞。如果警告是“气象站预测今天有 80% 的几率下雨,请带上你的雨伞”,那么这很有用,因为它提供了信息。
    • 更简洁:在预处理器定义下添加“_SCL_SECURE_NO_WARNINGS”(也在“C/C++”类别下)
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      或者,如果你使用 C++11 并且不想关闭警告,你可以选择替换

      boost::is_any_of(L"(,)")
      

      使用以下 lambda 表达式

      [](wchar_t &c) { for (auto candidate : { L'(', L',', L')' }) { if (c == candidate) return true; }; return false; }
      

      你也可以把它打包成一个宏

      【讨论】:

        【解决方案6】:
        • 转到 C++ 项目的属性

        • 扩展“C/C++”

        • 高级:禁用特定警告:4996

        【讨论】:

          猜你喜欢
          • 2011-02-11
          • 2016-08-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-21
          • 1970-01-01
          • 1970-01-01
          • 2022-06-26
          相关资源
          最近更新 更多