错误C4996:'std :: _ Copy_impl':带有可能不安全的参数的函数调用

时间:2013-09-29 14:59:19

标签: c++ visual-c++ visual-studio-2012 c++11

我知道这个问题在SO中被多次询问过,但这与其他问题不同。

Compiler Error: Function call with parameters that may be unsafe

Visual Studio Warning C4996

xutility(2227): warning C4996: 'std::_Copy_impl'

代码段失败

DWORD dwNumberOfNames = pExportDirectory->NumberOfNames;
LPDWORD dwNames = (LPDWORD)((LPBYTE)hDLL +  pExportDirectory->AddressOfNames);
std::vector< std::string > exports;
std::copy(
    dwNames, 
    dwNames + dwNumberOfNames, 
    [&exports, &hDLL](DWORD  dwFuncOffset)
{
    std::string fname = std::string((PCHAR)((PBYTE)hDLL + dwFuncOffset));
    exports.push_back(fname);
}
);

编译器错误

  

错误1错误C4996:'std :: _ Copy_impl':带参数的函数调用   这可能是不安全的 - 这个调用依赖于调用者来检查   传递的值是正确的。要禁用此警告,请使用   -D_SCL_SECURE_NO_WARNINGS。请参阅有关如何使用Visual C ++'Checked Iterators'C:\ Program Files(x86)\ Microsoft Visual Studio的文档   11.0 \ VC \ include \ xutility 2176

问题

考虑到C4996,表示该功能已标记为已弃用 问题在哪里?

  1. 使用std :: copy,MS认为它是不安全的并且会被弃用吗?
  2. 是因为我使用std::copyC Array
  3. 是因为我使用Lambda表达式的方式吗?
  4. 如果不推荐使用std :: copy,那么如果我需要可移植的话,还有什么选择。
  5. 注意

    我知道,如何压制警告,但我很想知道问题的根本原因?

    另外,对我来说同样重要的是,在不影响代码质量的情况下处理此问题的便携方式。

2 个答案:

答案 0 :(得分:6)

根据msdn:http://msdn.microsoft.com/en-us/library/x9f6s1wf.aspx

,您没有致电std::copy

该功能签名是这样的:

template<class InputIterator, class OutputIterator> 
   OutputIterator copy( 
      InputIterator _First,  
      InputIterator _Last,  
      OutputIterator _DestBeg 
   );

那里没有玩家/ lambda的地方。

您没有致电std::copy_ifhttp://msdn.microsoft.com/en-us/library/ee384415.aspx

template<class InputIterator, class OutputIterator, class BinaryPredicate>
   OutputIterator copy_if(
      InputIterator _First, 
      InputIterator _Last,
      OutputIterator _Dest,
      Predicate _Pred
    );

由于你没有输出迭代器,你的谓词也没有返回bool。

看起来你想要std::transformhttp://msdn.microsoft.com/en-us/library/391xya49.aspx

template<class InputIterator, class OutputIterator, class UnaryFunction> 
   OutputIterator transform( 
      InputIterator _First1,  
      InputIterator _Last1,  
      OutputIterator _Result, 
      UnaryFunction _Func 
   ); 

你应该在输出迭代器中返回你想要的值。所以它会是这样的:

std::transform(
    dwNames, 
    dwNames + dwNumberOfNames,
    std::back_inserter(exports),
    [&hDLL](DWORD  dwFuncOffset) // This lambda is WRONG
{
    // THIS LINE IS WRONG 
    std::string fname = std::string((PCHAR)((PBYTE)hDLL + dwFuncOffset));
    return fname;
}
);

我的lambda错了。您需要输入数组的ELEMENTS(我不确定类型)作为lambda的参数,并返回要插入exports向量的内容。

您可能也不了解back_inserter。它位于<iterator>标题中。请参见此处:http://msdn.microsoft.com/en-us/library/12awccbs.aspx和此处:http://www.cplusplus.com/reference/iterator/back_inserter/

这可能不是100%的答案,但有了这个,我想你可以到达你想去的地方。

答案 1 :(得分:1)

它本身不是std::copy,我认为你的问题是使用LPDWORD进行复制,这使得Visuall C ++认为你正在进行C字符串复制,因为LPDWORD不是一个经过检查的迭代器。

http://msdn.microsoft.com/en-us/library/ttcz0bys(v=vs.120).aspx