7

我知道这个问题在 SO 中被问过很多次,但这是与其他问题的不同之处。

编译器错误:使用可能不安全的参数调用函数

Visual Studio 警告 C4996

xutility(2227): 警告 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. MS认为是不安全并且会被弃用的std :: copy的使用吗?
  2. 是因为我用过std::copyC Array
  3. 是因为我使用 Lambda 表达式的方式吗?
  4. 如果不推荐使用 std::copy ,如果我需要便携,还有什么替代方法。

笔记

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

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

4

2 回答 2

6

您没有std::copy根据 msdn 调用:http: //msdn.microsoft.com/en-us/library/x9f6s1wf.aspx

该函数签名是这样的:

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

那里没有仿函数/ lambda 的位置。

你也没有打电话std::copy_if:http: //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
    );

由于您没有输出迭代器,您的谓词也没有返回布尔值。

看起来你想要std::transform:http: //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% 的答案,但有了这个,我认为你可以到达你想去的地方。

于 2013-10-15T18:02:15.200 回答
1

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

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

于 2013-09-29T15:05:56.520 回答