warning C4996: ‘std::_Copy_impl’: Function call with parameters that may be - 小众知识

warning C4996: ‘std::_Copy_impl’: Function call with parameters that may be

2013年01月27日 14:18:05 苏内容
  标签: C4996/boost
阅读:255

编译protobuffer ,出现了两个问题

1.vs加载项目后,会发现min函数 没有引入头文件   #include

2.vs2013编译测试类的时候,抛出了以下异常:

warning 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’

解决的方案请看:http://choorucode.com/2010/08/30/visual-c-c4996-warning-on-copy-with-array-parameters/

 

protobuffer 中抛出异常的头文件是repeated_field.h中第708行,修改后的代码如下:

template
void ElementCopier::operator()(
    Element to[], const Element from[], int array_size) {
    std::copy(from, from + array_size, stdext::checked_array_iterator(to,array_size));
    //std::copy(from, from + array_size, to);
}

 

通过以上修改编译成功   




在C++ PRIMER中模拟实现vector容器所给的代码中,如果你用的是vs 2012的话,那么你会发现根本就不能通过编译,这时应该怎么办呢?

有问题代码为:uninitialized_copy(elements , first_free , newelements) ;
上述代码的目的是把elements到first_free之间的内存中的数据复制到以newelements开始的内存中
 
首先把这段代码放到vs 2010进行编译、运行你会发现只是弹出了如下的信息,但是能正确运行。
 
warning C4996: 'std::_Uninitialized_copy0': 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'
 
在vs 2012中进行编译会弹出如下信息:
 
error C4996: 'std::_Uninitialized_copy0': 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'
 
 
有上述代码的功能我想可以想到用如下的代码替代它:copy(elements , first_free , newelements) ; 
 
此时你会发现在vs 2012中的编译信息如下:
 
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'
 
而在vs 2010中却仍可以正确编译并运行,所显示的编译信息如下:
 
warning 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'
 
从编译的信息来看vs 2012有点矛盾的地方,也即error C4996 ... To disable this warning前面说是error后面却成了warning,逻辑上不太相符,当然这不排除是汉化引起的。
 
在vs 2012中不能像C++ PRIMER中所描述的那样使用这两个函数的原因是在vs 2012中提升了安全机制,在这里如果我们还是想直接使用这两个函数那么,我们可以在使用前添加如下的宏定义:
 
#ifndef _SECURE_SCL
#define _SECURE_SCL 0
#else
#undef _SECURE_SCL
#define _SECURE_SCL 0
#endif
 
 
#ifndef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL 0
#else
#undef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL 0
#endif
 
当然我们也可以不用这两个函数,而使用其它的函数来完成相同的功能,如以下几个函数:
 
1、用头文件algorithm中提供的模板函数copy(FwdIt first, FwdIt last, const T& x)来提供:
添加上述的宏定义,然后用
copy(elements , first_free , newelements) ; 
 
2、用头文件memory中allocator类提供的操作constuct(p , t)来提供:
for(ptrdiff_t i=0 ; i
   alloc.construct(newelements+i , elements[i]) ;
 
3、用头文件memory中提供的模板函数uninitialized_fill(FwdIt first, FwdIt last, const T& x)来提供:
for(ptrdiff_t i=0 ; i
   uninitialized_fill(newelements+i , newelements+i+1 , elements[i]) ;
 
4、用头文件algorithm中提供的模板函数fill(FwdIt first, FwdIt last, const T& x)来提供:
for(ptrdiff_t i=0 ; i
   fill(newelements+i , newelements+i+1 , elements[i]) ;
 
5、用头文件memory.h中提供的函数memcpy( void *dest, const void *src, size_t count )或memmove( void *dest, const void *src, size_t count )来提供:(T是所写的模板类的模板参数)
memcpy(newelements , elements , size*sizeof(T)) ;
memmove(newelements , elements , size*sizeof(T)) ;
 
 
 
下面对上面用到的宏进行简单的介绍:
 
_SECURE_SCL (SCL) macro defines whether Checked Iterators(Checked iterators ensure that the bounds of your container are not overwritten) are enabled.
 If defined as 1, unsafe iterator use causes a runtime error and the program is terminated.
 If defined as 0, checked iterators are disabled.
 In debug mode, the default value for _SECURE_SCL is 1, meaning checked iterators are enabled. 
 In release mode, the default value for _SECURE_SCL is 0.
 
 
_HAS_ITERATOR_DEBUGGING (HID) macro defines whether the iterator debugging feature is enabled in a debug build.
 By default, iterator debugging is enabled. 
 
 
The following section describes the possible values of the SCL and HID macros :
SCL=0    Disables checked iterators.
SCL=1    Enables checked iterators.
HID=0    Disables iterator debugging in debug builds.
HID=1    Enables iterator debugging in debug builds. HID cannot be enabled in release builds.
 
 
The _ITERATOR_DEBUG_LEVEL (IDL) macro supersedes and combines the functionality of the _SECURE_SCL (SCL) and _HAS_ITERATOR_DEBUGGING (HID) macros.
 
 
The following table describes how the IDL macro values supersede the SCL and HID macro values :
 

Compilation mode

New macro

Old macros

Description

Debug

 

 

 

 

IDL=0

SCL=0, HID=0

Disables checked iterators and disables iterator debugging.

 

IDL=1

SCL=1, HID=0

Enables checked iterators and disables iterator debugging.

 

IDL=2 (Default)

SCL=(does not apply), HID=1

By default, enables iterator debugging; checked iterators are not relevant.

Release

 

 

 

 

IDL=0 (Default)

SCL=0

By default, disables checked iterators.

 

IDL=1

SCL=1

Enables checked iterators; iterator debugging is not relevant.


解决use -D_SCL_SECURE_NO_WARNINGS的问题
分类: 错误处理 2014-06-06 19:01 4083人阅读 评论(1) 收藏 举报
vc2012报错了:
1>c:\program files (x86)\microsoft visual studio11.0\vc\include\xutility(2176): error C4996: 'std::_Copy_impl': Function callwith parameters that may be unsafe - this call relies on the caller to checkthat the passed values are correct. To disable this warning, use-D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'CheckedIterators'
 
 
 
加入预处理器(项目属性----C/C++----预处理----预处理器定义):
_SCL_SECURE_NO_WARNINGS
 
 
 
即可解决

 

大家看看我的这个警告?怎么解决

bool ranking_manager::split_string(std::vector &vec,std::string str,const char *p)
{
    s_uint32 number;
    std::vector strvec_;
 
    if(vec.size()<=0 || str.length() == 0)
        return false;
    //使用boost自带进行字符串的分割
    boost::split(strvec_, str, boost::is_any_of(p), boost::token_compress_on);
    //类型转换string转换为int
    std::vector::iterator it  = strvec_.begin();
    for(it;it!= strvec_.end();++it)
    {
        std::stringstream stream;
        stream << *it;
        stream >> number;
        vec.push_back(number);
    }
    strvec_.clear();
    return true;
}

e:\soft\vs2010\vc\include\xutility(2239): warning 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'
2>          e:\soft\vs2010\vc\include\xutility(2224) : 参见“std::_Copy_impl”的声明
2>          d:\d3\project\source\tools\boost_1_51_0\boost\algorithm\string\detail\classification.hpp(102): 参见对正在编译的函数 模板 实例化“_OutIt std::copy(_InIt,_InIt,_OutIt)”的引用
2>          with
2>          [
2>              _OutIt=char *,
2>              _InIt=const char *
2>          ]
2>          d:\d3\project\source\tools\boost_1_51_0\boost\algorithm\string\classification.hpp(206): 参见对正在编译的函数 模板 实例化“boost::algorithm::detail::is_any_ofF::is_any_ofF>(const RangeT &)”的引用
2>          with
2>          [
2>              CharT=char,
2>              IteratorT=const char *,
2>              RangeT=boost::iterator_range
2>          ]
2>          d:\d3\project\source\server\game\src\logic\ranking\ranking_manager.cpp(233): 参见对正在编译的函数 模板 实例化“boost::algorithm::detail::is_any_ofF boost::algorithm::is_any_of(const RangeT &)”的引用
2>          with
2>          [
2>              CharT=char,
2>              RangeT=const char *
2>          ]e:\soft\vs2010\vc\include\xutility(2239): warning 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'
2>          e:\soft\vs2010\vc\include\xutility(2224) : 参见“std::_Copy_impl”的声明
2>          d:\d3\project\source\tools\boost_1_51_0\boost\algorithm\string\detail\classification.hpp(102): 参见对正在编译的函数 模板 实例化“_OutIt std::copy(_InIt,_InIt,_OutIt)”的引用
2>          with
2>          [
2>              _OutIt=char *,
2>              _InIt=const char *
2>          ]
2>          d:\d3\project\source\tools\boost_1_51_0\boost\algorithm\string\classification.hpp(206): 参见对正在编译的函数 模板 实例化“boost::algorithm::detail::is_any_ofF::is_any_ofF>(const RangeT &)”的引用
2>          with
2>          [
2>              CharT=char,
2>              IteratorT=const char *,
2>              RangeT=boost::iterator_range
2>          ]
2>          d:\d3\project\source\server\game\src\logic\ranking\ranking_manager.cpp(233): 参见对正在编译的函数 模板 实例化“boost::algorithm::detail::is_any_ofF boost::algorithm::is_any_of(const RangeT &)”的引用
2>          with
2>          [
2>              CharT=char,
2>              RangeT=const char *
2>          ]

这个要怎么改,没看明白?

#define _SCL_SECURE_NO_WARNINGS



 

I got this warning message.. but i dont know what/where the problem is..!

includes

#pragma warning(push)
#pragma warning(disable:4996)
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/ostream_iterator.hpp>
#pragma warning(pop)
and the warning

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(2227): warning 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'
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\xutility(2212): Siehe Deklaration von 'std::_Copy_impl'
1>          c:\users\perlig\documents\visual studio 2010\projects\restmanager\restmanager\**http.cpp(257)**: Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "_OutIt std::copy<boost::archive::iterators::insert_linebreaks<Base,N>,boost::archive::iterators::ostream_iterator<Elem>>(_InIt,_InIt,_OutIt)".
1>          with
1>          [
1>              _OutIt=boost::archive::iterators::ostream_iterator<char>,
1>              Base=boost::archive::iterators::base64_from_binary<boost::archive::iterators::transform_width<const char *,6,8>>,
1>              N=76,
1>              Elem=char,
1>                _InIt=boost::archive::iterators::insert_linebreaks<boost::archive::iterators::base64_from_binary<boost::archive::iterators::transform_width<const char *,6,8>>,76>
1>          ]
the code occur in line 257 as the warning message says. but i´m not able to fix it because i not know what is wrong..

string data contains a "user:password" string for basic auth via http.

http.cpp(257):

// typdef, prepare
using namespace boost::archive::iterators;
stringstream os;
typedef
    insert_linebreaks<         // insert line breaks every 72 characters
        base64_from_binary<    // convert binary values ot base64 characters
            transform_width<   // retrieve 6 bit integers from a sequence of 8 bit bytes
                const char *,
                6,
                8
            >
        >
        ,76
    >
    base64_text; // compose all the above operations in to a new iterator

// encrypt
#pragma warning(push)
#pragma warning(disable:4996)
copy( //<<<<<------ LINE 257
    base64_text(data.c_str()),
    base64_text(data.c_str() + data.size()),
    boost::archive::iterators::ostream_iterator<char>(os)
);
#pragma warning(pop)
anybody got any idea?


I think you know what is the meaning of the warning but first I describe the warning and then say what to do to get rid of it. Microsoft implemented a new security enabled set of function in its CRT, STL, MFC, ... and mark old version of those functions as deprecated to provide a hint for you that you should migrate to new secure version. so it say std::copy is unsafe!! how? as follow:

char storage[ 10 ], *p = storage;
std::copy( std::istream_iterator<int>(std::cin), std::istream_iterator<int>(), p );
Now what will happened if user input more than 10 int? the memory will be overwritten and you corrupted your memory.

Using boost::archive::iterators::ostream_iterator is perfectly safe but since it does not follow the design of safe iterators in MSVC it will considered as unsafe.

Now you should either disable this warning by -D_SCL_SECURE_NO_WARNINGS to cl input flags or add a pragma to disable this warning( as you do ), but why pragma don't work?

the reason is obvious, this pragma work on scope and the scope that you use pragma on it have nothing wrong, you must guard xutility with this pragma and every thing will work as expected.

扩展阅读