Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe

I know this question was asked numerous times in SO, but this is a variation from the rest.

Compiler Error: Function call with parameters that may be unsafe

Visual Studio Warning C4996

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

Failing Code Snippet

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);
}
);

Compiler Error

Error 1 error C4996: 'std::_Copy_impl': 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' C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xutility 2176

Question

Considering, C4996, means the function was marked to be deprecated Where is the problem?

  1. Is it the use of std::copy, that MS thinks is unsafe and would be deprecated?
  2. Is it because I have used std::copy with a C Array?
  3. Is it because of the way I am using Lambda expression?
  4. If std::copy is deprecated, what is the alternative, if I need to be portable.

Note

I know, how to suppress the warning, but I am curious to know, the root cause of the problem?

Also, equally important for me to know, the portable way to handle this issue without compromising code quality.

like image 754
Abhijit Avatar asked Sep 29 '13 14:09

Abhijit


2 Answers

You aren't calling std::copy according to msdn: http://msdn.microsoft.com/en-us/library/x9f6s1wf.aspx

That function signature is this:

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

There's no place for a functor/lambda there.

You're not calling std::copy_if either: 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
    );

As you have no output iterator, nor does your predicate return a bool.

It looks like you want 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 
   ); 

And you should be returning the value you want in the output iterator. So it'll be something like this:

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;
}
);

My lambda is wrong. You need the input of the ELEMENTS of your array (I'm not sure of the type) as the argument to the lambda, and return what you want inserted into the exports vector.

You probably also didn't know about back_inserter. It's in the <iterator> header. See here: http://msdn.microsoft.com/en-us/library/12awccbs.aspx and here: http://www.cplusplus.com/reference/iterator/back_inserter/

That may not be 100% of the answer, but with that, I think you can get to where you want to go.

like image 57
Kevin Anderson Avatar answered Oct 18 '22 06:10

Kevin Anderson


It is not std::copy itself, I think your problem is to use LPDWORD to do the copy which makes Visuall C++ thinks you are doing C string copy because LPDWORD is not a checked iterator.

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

like image 32
CS Pei Avatar answered Oct 18 '22 06:10

CS Pei