Boost C++ Libraries: Ticket #11426: Warning C4996 at using std::fill_n https://svn.boost.org/trac10/ticket/11426 <h2 class="section" id="Problem">Problem</h2> <p> We develop project using <strong>msvc 2013</strong>. </p> <p> Warning appear just after include &lt;boost/random/mersenne_twister.hpp&gt; During compilation <strong>debug</strong> version with default settings. </p> <p> After compilation I take warning: </p> <pre class="wiki">1&gt;C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xutility(2715): warning C4996: 'std::_Fill_n': 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&gt; C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xutility(2701) : see declaration of 'std::_Fill_n' 1&gt; X:\xxx\boost_1_58_0\boost/random/detail/polynomial.hpp(126) : see reference to function template instantiation '_OutIt std::fill_n&lt;boost::random::detail::polynomial_ops::digit_t*,size_t,boost::random::detail::polynomial_ops::digit_t&gt;(_OutIt,_Diff,const _Ty &amp;)' being compiled 1&gt; with 1&gt; [ 1&gt; _OutIt=boost::random::detail::polynomial_ops::digit_t * 1&gt; , _Diff=size_t 1&gt; , _Ty=boost::random::detail::polynomial_ops::digit_t 1&gt; ] </pre><p> problem source code is: </p> <pre class="wiki"> static void multiply(const digit_t * lhs, std::size_t lhs_size, const digit_t * rhs, std::size_t rhs_size, digit_t * output) { std::fill_n(SilenceMSVC_C4996(output), lhs_size + rhs_size, digit_t(0)); // &lt;&lt;&lt;&lt;&lt;&lt; problem line multiply_add(lhs, lhs_size, rhs, rhs_size, output); } </pre><h2 class="section" id="Cause">Cause</h2> <p> Warning appear because <strong>Visual C++ Checked Iterators</strong> is enabled. See <a class="ext-link" href="https://msdn.microsoft.com/en-us/library/vstudio/aa985965%28v=vs.120%29.aspx"><span class="icon">​</span>https://msdn.microsoft.com/en-us/library/vstudio/aa985965%28v=vs.120%29.aspx</a>. </p> <p> This tecnology don't allow use pointer with std::fill_n (and others). And so we take warning. </p> <h2 class="section" id="Disablewarningdontwork">Disable warning don't work!</h2> <p> Try disable warning. </p> <pre class="wiki">// some std library #include &lt;map&gt; #include &lt;algorithm&gt; #pragma warning(disable:4996) #include &lt;boost/random/mersenne_twister.hpp&gt; </pre><p> Warning is still exist. As I understand. MSVC think what warning appear in xutility (not in polynomial.hpp). Because if add #pragma at start of the program then warning will be disabled. </p> <p> But disable this warning in xutility is wrong. </p> <h2 class="section" id="Decision">Decision</h2> <p> There is one case is described at MS article <a class="ext-link" href="https://msdn.microsoft.com/en-us/library/vstudio/aa985965%28v=vs.120%29.aspx"><span class="icon">​</span>https://msdn.microsoft.com/en-us/library/vstudio/aa985965%28v=vs.120%29.aspx</a> - using <strong>stdext::make_checked_array_iterator</strong>. </p> <pre class="wiki"> // WARNING C4996: Pointers cannot be checked in debug mode // (an overrun will trigger undefined behavior) int a6[16]; int * p6 = a6; transform(v.begin(), v.end(), p6, [](int n) { return n * 6; }); print("a6: ", a6); // OK: stdext::checked_array_iterator is checked in debug mode // (an overrun will trigger a debug assertion) int a7[16]; int * p7 = a7; transform(v.begin(), v.end(), stdext::make_checked_array_iterator(p7, 16), [](int n) { return n * 7; }); print("a7: ", a7); </pre><p> I wrote decision: </p> <pre class="wiki">// Silence using pointer in std::find and others. &gt;= Visual Studio 2013, debug. #ifndef SilenceMSVC_C4996 #if BOOST_WORKAROUND(BOOST_MSVC, &gt;= 1800) &amp;&amp; _ITERATOR_DEBUG_LEVEL != 0 #define SilenceMSVC_C4996(pointer) stdext::make_unchecked_array_iterator(pointer) #else #define SilenceMSVC_C4996(pointer) pointer #endif #endif </pre><p> And replace calling std::fill_n with next code: </p> <pre class="wiki">std::fill_n(SilenceMSVC_C4996(output), lhs_size + rhs_size, digit_t(0)); </pre><p> </p> <h2 class="section" id="Otherwarningplaces">Other warning places</h2> <p> I also used this macros in:<br /> <em>boost\random\detail\polynomial.hpp</em>:<br /> static void mod_pow_x(boost::uintmax_t exponent, const digit_t * mod, std::size_t mod_bits, digit_t * out) </p> <p> replace (2 times): </p> <pre class="wiki">std::fill_n(out + 1, n - 1, digit_t(0)); </pre><p> to </p> <pre class="wiki">std::fill_n(SilenceMSVC_C4996(out + 1), n - 1, digit_t(0)); </pre><p> In <em>boost/algorithm/string/detail/classification.hpp</em>:<br /> </p> <p> replace: </p> <pre class="wiki">::std::copy(::boost::begin(Range), ::boost::end(Range), Storage); </pre><p> to </p> <pre class="wiki">::std::copy(::boost::begin(Range), ::boost::end(Range), SilenceMSVC_C4996(Storage));}}} </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11426 Trac 1.4.3 Steven Watanabe Sat, 13 Feb 2016 15:31:14 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/11426#comment:1 https://svn.boost.org/trac10/ticket/11426#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> I'm not going to change correct code that the standard is explicitly designed to allow, just because msvc has unilaterally decided that it's bad. </p> Ticket