[Boost-bugs] [Boost C++ Libraries] #11426: Warning C4996 at using std::fill_n

Subject: [Boost-bugs] [Boost C++ Libraries] #11426: Warning C4996 at using std::fill_n
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-06-29 05:00:35


#11426: Warning C4996 at using std::fill_n
----------------------------------------------+---------------------------
 Reporter: Yury Podpruzhnikov <QWERTYura@…> | Owner: no-maintainer
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: random
  Version: Boost 1.58.0 | Severity: Problem
 Keywords: |
----------------------------------------------+---------------------------
 == Problem ==

 We develop project using '''msvc 2013'''.

 Warning appear just after include <boost/random/mersenne_twister.hpp>
 During compilation '''debug''' version with default settings.

 After compilation I take warning:

 {{{
 1>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> C:\Program Files (x86)\Microsoft Visual Studio
 12.0\VC\include\xutility(2701) : see declaration of 'std::_Fill_n'
 1> X:\xxx\boost_1_58_0\boost/random/detail/polynomial.hpp(126) :
 see reference to function template instantiation '_OutIt
 std::fill_n<boost::random::detail::polynomial_ops::digit_t*,size_t,boost::random::detail::polynomial_ops::digit_t>(_OutIt,_Diff,const
 _Ty &)' being compiled
 1> with
 1> [
 1> _OutIt=boost::random::detail::polynomial_ops::digit_t *
 1> , _Diff=size_t
 1> , _Ty=boost::random::detail::polynomial_ops::digit_t
 1> ]
 }}}

 problem source code is:
 {{{
     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)); // <<<<<< problem line
         multiply_add(lhs, lhs_size, rhs, rhs_size, output);
     }

 }}}

 == Cause ==

 Warning appear because '''Visual C++ Checked Iterators''' is enabled.
 See [https://msdn.microsoft.com/en-
 us/library/vstudio/aa985965%28v=vs.120%29.aspx].

 This tecnology don't allow use pointer with std::fill_n (and others).
 And so we take warning.


 == Disable warning don't work! ==

 Try disable warning.
 {{{
 // some std library
 #include <map>
 #include <algorithm>

 #pragma warning(disable:4996)
 #include <boost/random/mersenne_twister.hpp>
 }}}
 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.

 But disable this warning in xutility is wrong.

 == Decision ==

 There is one case is described at MS article [https://msdn.microsoft.com
 /en-us/library/vstudio/aa985965%28v=vs.120%29.aspx] - using
 '''stdext::make_checked_array_iterator'''.
 {{{
     // 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);
 }}}

 I wrote decision:

 {{{
 // Silence using pointer in std::find and others. >= Visual Studio 2013,
 debug.
 #ifndef SilenceMSVC_C4996
 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1800) && _ITERATOR_DEBUG_LEVEL != 0
 #define SilenceMSVC_C4996(pointer)
 stdext::make_unchecked_array_iterator(pointer)
 #else
 #define SilenceMSVC_C4996(pointer) pointer
 #endif
 #endif
 }}}

 And replace calling std::fill_n with next code:

 {{{
 std::fill_n(SilenceMSVC_C4996(output), lhs_size + rhs_size, digit_t(0));
 }}}

 == Other warning places ==
 I also used this macros in:[[BR]]
 ''boost\random\detail\polynomial.hpp'':[[BR]]
 static void mod_pow_x(boost::uintmax_t exponent, const digit_t * mod,
 std::size_t mod_bits, digit_t * out)

 replace (2 times):
 {{{
 std::fill_n(out + 1, n - 1, digit_t(0));
 }}}
 to
 {{{
 std::fill_n(SilenceMSVC_C4996(out + 1), n - 1, digit_t(0));
 }}}

 In ''boost/algorithm/string/detail/classification.hpp'':[[BR]]

 replace:
 {{{
 ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage);
 }}}
 to
 {{{
 ::std::copy(::boost::begin(Range), ::boost::end(Range),
 SilenceMSVC_C4996(Storage));}}}
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/11426>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:18 UTC