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

17,399

Solution 1

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.

Solution 2

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

Share:
17,399
Abhijit
Author by

Abhijit

Updated on June 27, 2022

Comments

  • Abhijit
    Abhijit almost 2 years

    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.

  • Abhijit
    Abhijit over 10 years
    I appreciate your answer. Do you have a reason for your speculation? The compiler error refers to std::_Copy_impl, not to a strcpy. And where are you seeing a call to strcpy?
  • Admin
    Admin over 10 years
    The message, present in the question, strongly suggests that it is std::copy itself that is warned about, and also, the question does not use char * (not where the warning is, anyway).
  • CS Pei
    CS Pei over 10 years
    I have this exactly warning before with strcpy, strlen, etc. I just checked, this warning is because you do not use a checked iterator.
  • Abhijit
    Abhijit over 10 years
    @JohnSmith: Is checked iterator part of the C++ standard, or MS specific? Would that make my code portable? And what is the correct way to use stdext::checked_array_iterator with a lambda expression?
  • CS Pei
    CS Pei over 10 years
    I think checked iterator is MS specific. stdext is from MS I believe. I don't know the answer to lambda part.
  • Mooing Duck
    Mooing Duck about 10 years
    He almost seems to be using std::for_each