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?
std::copy
with a C Array
?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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With