46

I have a simple C++ with Boost like this:

#include <boost/algorithm/string.hpp>

int main()
{
  std::string latlonStr = "hello,ergr()()rg(rg)";
  boost::find_format_all(latlonStr,boost::token_finder(boost::is_any_of("(,)")),boost::const_formatter(" "));

This works fine; it replaces every occurrence of ( ) , with a " "

However, I get this warning when compiling:

I'm using MSVC 2008, Boost 1.37.0.

1>Compiling...
1>mainTest.cpp
1>c:\work\minescout-feat-000\extlib\boost\algorithm\string\detail\classification.hpp(102) : warning C4996: 'std::copy': 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'
1>        c:\program files (x86)\microsoft visual studio 9.0\vc\include\xutility(2576) : see declaration of 'std::copy'
1>        c:\work\minescout-feat-000\extlib\boost\algorithm\string\classification.hpp(206) : see reference to function template instantiation 'boost::algorithm::detail::is_any_ofF<CharT>::is_any_ofF<boost::iterator_range<IteratorT>>(const RangeT &)' being compiled
1>        with
1>        [
1>            CharT=char,
1>            IteratorT=const char *,
1>            RangeT=boost::iterator_range<const char *>
1>        ]
1>        c:\work\minescout-feat-000\minescouttest\maintest.cpp(257) : see reference to function template instantiation 'boost::algorithm::detail::is_any_ofF<CharT> boost::algorithm::is_any_of<const char[4]>(RangeT (&))' being compiled
1>        with
1>        [
1>            CharT=char,
1>            RangeT=const char [4]
1>        ]

I could certainly disable the warning using

-D_SCL_SECURE_NO_WARNINGS

but I'm a bit reluctant to do that before I find out what's wrong, or more importantly if my code is incorrect.

6 Answers 6

52

It is nothing to worry about. In the last few releases of MSVC, they've gone into full security-paranoia mode. std::copy issues this warning when it is used with raw pointers, because when used incorrectly, it can result in buffer overflows.

Their iterator implementation performs bounds checking to ensure this doesn't happen, at a significant performance cost.

So feel free to ignore the warning. It doesn't mean there's anything wrong with your code. It is just saying that if there is something wrong with your code, then bad things will happen. Which is an odd thing to issue warnings about. ;)

5
  • 24
    This warning drives me nuts, its like the "warning" about the contents of a cup of coffee being hot.
    – Clay
    Commented Aug 19, 2009 at 17:20
  • 9
    the worst thing about it is that there is no sane "fix". Most warnings are issued because there is a better, less error-prone way to achieve the same thing. They can be fixed. What are you supposed to do about this one? If you have a raw C array and you need to copy data to or from it, pointers are the only type of iterators available. std::copy is by far the best an safest option to use. Or are they suggesting we go back to writing for loops to achieve the same thing? Commented Aug 19, 2009 at 17:58
  • I bet 100 rep that it'll be removed in the first SP along with the other "don't they test what they release?" issues... Commented Dec 19, 2010 at 16:03
  • 1
    Ironically a workaround is to use memcpy instead. It's probably worse from a security point of view but the compiler likes it.
    – Laserallan
    Commented Jan 31, 2012 at 2:19
  • 3
    As described in this answer to a similar (duplicate?) question, to ignore the warning in Visual Studio, go to Project properties->C++->Advanced->Disable specific warnings and type in 4996.
    – sgryzko
    Commented Sep 25, 2014 at 18:23
26

You can also disable this warning in specific headers:

#if defined(_MSC_VER) && _MSC_VER >= 1400 
#pragma warning(push) 
#pragma warning(disable:4996) 
#endif 

/* your code */ 

#if defined(_MSC_VER) && _MSC_VER >= 1400 
#pragma warning(pop) 
#endif 
1
  • 9
    Not necessarily; for example the header <xutility>, which contains an implementation of std::copy marked as deprecated and whose usage yields this warning, has #pragma warning(push,3) at the very top, causing the compiler to override your warning settings with Level 3 defaults. Commented Jul 19, 2012 at 15:09
19

If you feel safe about disabling this error:

  • Go to the properties of your C++ project
  • Expand the "C/C++"
  • Highlight "Command Line"
  • Under "Additional Options" append the following to any text that might be in that box

" -D_SCL_SECURE_NO_WARNINGS"

3
  • 2
    Remember that even if you're sure that your current code is safe, you may eventually code something unsafe and you would not be warned about it.
    – Bluebaron
    Commented Oct 25, 2011 at 13:19
  • 2
    Yes, but in this case it is like saying, "Take your umbrella, it may rain today." Being told that every day is not useful because it provides no information, even in the Shannon sense. Eventually, it will rain and you will have been warned to take your umbrella. If the warning was, "Weather station predicted rain today 80% chance, take your umbrella," then that is useful since it provides information. Commented Feb 26, 2012 at 19:16
  • 6
    a little cleaner: add "_SCL_SECURE_NO_WARNINGS" under Preprocessor Definitions (which is also under the "C/C++" category) Commented Mar 14, 2013 at 22:38
8

The warning comes from Visual Studio's non-standard "safe" library checks introduced starting with MSVC 8.0. Microsoft has identified "potentially dangerous" APIs and has injected warnings discouraging their use. While it is technically possible to call std::copy in an unsafe way, 1) receiving this warning does not mean you are doing so, and 2) using std::copy as you normally should is not dangerous.

2

Alternatively, if you use C++11 and don't want to turn off warnings, you have the painful option of replacing

boost::is_any_of(L"(,)")

with the following lambda expression

[](wchar_t &c) { for (auto candidate : { L'(', L',', L')' }) { if (c == candidate) return true; }; return false; }

You can also possibly pack that into a macro

1
  • Go to the properties of your C++ project

  • Expand the "C/C++"

  • Advanced: Disable Specific Warnings: 4996

Not the answer you're looking for? Browse other questions tagged or ask your own question.