微软可以安全地替代std :: reverse_copy吗?

时间:2016-01-25 01:48:06

标签: c++ visual-c++ stl

我有以下代码:

Integer::Integer(const byte *encodedInteger, size_t byteCount, Signedness s, ByteOrder o)
{
    if(o == LITTLE_ENDIAN_ORDER)
    {
        SecByteBlock block(byteCount);
        std::reverse_copy(encodedInteger, encodedInteger+byteCount, block.begin());

        Decode(block.begin(), block.size(), s);
        return;
    }
    ...
}

我在std::reverse_copy上抓了C4996 warning

1>c:\Program Files\...\VC\include\algorithm(2184): warning C4996: 'std::_Reverse_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:\...\VC\include\algorithm(2168) : see declaration of 'std::_Reverse_copy'
1>          integer.cpp(2898) : see reference to function template instantiation '_OutIt std::reverse_copy<const byte*,unsigned char*>(_BidIt,_BidIt,_OutIt)' being compiled
1>          with
1>          [
1>              _OutIt=unsigned char *,
1>              _BidIt=const byte *
1>          ]

我很乐意提供目标缓冲区大小或最后一个目标元素,以符合Microsoft平台上的最佳做法。

byteCount 是一个参数(并且不是编译时常量),所以我不能使用目标缓冲区大小调用重载( count 模板参数):

std::reverse_copy<byte*, byte*, count>(...);

我也天真地尝试添加目标缓冲区大小和最后一个元素,但是它们导致编译错误&#34;期望3个参数 - 提供4个&#34;

std::reverse_copy(encodedInteger, encodedInteger+byteCount, block.begin(), block.begin()+block.size());

什么是Microsoft的std :: reverse_copy的安全替代,允许我指定目标缓冲区大小?

以下是Microsoft从<algorithm>提供的重载:

template<class _BidIt,
    class _OutIt> inline
_SCL_INSECURE_DEPRECATE
    _OutIt _Reverse_copy(_BidIt _First, _BidIt _Last,
        _OutIt _Dest,
        _STD tr1::false_type)
    {   // copy reversing elements in [_First, _Last), unchecked dest
    return (_Reverse_copy(_First, _Last,
        _Dest, _Iter_cat(_First), _Iter_cat(_Dest)));
    }

template<class _BidIt,
    class _OutIt> inline
    _OutIt reverse_copy(_BidIt _First, _BidIt _Last,
        _OutIt _Dest)
    {   // copy reversing elements in [_First, _Last)
    _DEBUG_RANGE(_First, _Last);
    _DEBUG_POINTER(_Dest);
    return (_Reverse_copy(_Unchecked(_First), _Unchecked(_Last),
        _Dest, _Is_checked(_Dest)));
    }

template<class _BidIt,
    class _OutTy,
    size_t _OutSize> inline
    _OutTy *reverse_copy(_BidIt _First, _BidIt _Last,
        _OutTy (&_Dest)[_OutSize])
    {   // copy reversing elements in [_First, _Last), array dest
    return (_Unchecked(
        _STD reverse_copy(_First, _Last,
            _Array_iterator<_OutTy, _OutSize>(_Dest))));
    }

1 个答案:

答案 0 :(得分:2)

问题不在于功能。编译器只是(帮助)通知您代码是不安全的,因为无法在调试模式下检查指针,因此任何溢出都会导致未定义的行为。

VC ++提供了一个专门用于此目的的函数,称为stdext::make_checked_array_iterator。像这样使用它:

std::reverse_copy(encodedInteger, encodedInteger+byteCount, 
     stdext::make_checked_array_iterator(block.begin(), block.size()));