diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2016-04-01 23:55:25 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2016-04-26 16:36:40 +0000 |
commit | 31c7b24aa5f57fbe8258c9e9845c8d630af4aec1 (patch) | |
tree | 4ff8ecc6373f1d789f613df4d6042432a53427c0 /src/corelib/tools/qvarlengtharray.h | |
parent | 3a8f895d3529d59b7a1ea35705f86a2fcdeb35e4 (diff) |
Silence MSVC warnings when using certain std algorithms
The MSVC STL warns when passing naked pointers as non-bounded
iterators to algorithms such as std::equal and std::copy, in
an attempt to inform users that the range specified by that
iterator has an implicit minimum size that the caller of the
algorithm must ensure is met:
warning C4996: 'std::_Equal1': 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'
When building Qt, as well as when building user projects with
qmake (cf. 0a76b6bc7f98900ea884cd10ccca1a332e5bdba5), we
globally disable this warning (with -D_SCL_SECURE_NO_WARNINGS),
but since we started using STL algorithms in public headers (e.g.
in qvector.h), users get this warning in their own projects now,
unless they, too, define said macro. But such a requirement is
against the Qt policy to have headers that are warning-free as
much as possible.
The suggested way of fixing this warning is to wrap the naked
pointer in a stdext::unchecked_array_iterator before passing it
to the algorithm, cf. examples in
https://msdn.microsoft.com/en-us/library/ttcz0bys%28v=vs.120%29.aspx
or, together with the capacity-made-explicit, in a
stdext::checked_array_iterator.
To avoid ifdefs for platforms that don't have these extensions
(which, incidentally, for the unchecked case, includes MSVC 2012),
wrap the calls in macros.
The end game here is to drop -D_SCL_SECURE_NO_WARNINGS, at least
for public headers, even though this commit also adds the wrapper
to implementation and private header files.
An alternative to the wrapper would have been the version of
std::equal that takes four iterators. However, that is a C++14
library feature, while this version of Qt still needs to compile
with a C++98 compiler, and, more importantly, there isn't, and
never will be, a corresponding 4-iterator version of std::copy.
Task-number: QTBUG-47948
Done-with: Stephen Kelly <steveire@gmail.com>
Change-Id: I1bbab257fb5f1c5042939c382a412b596112ff26
Reviewed-by: Stephen Kelly <ske@ableton.com>
Diffstat (limited to 'src/corelib/tools/qvarlengtharray.h')
-rw-r--r-- | src/corelib/tools/qvarlengtharray.h | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index bb15d66439..8371352061 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -96,7 +96,8 @@ public: QVarLengthArray<T, Prealloc> &operator=(std::initializer_list<T> list) { resize(list.size()); - std::copy(list.begin(), list.end(), this->begin()); + std::copy(list.begin(), list.end(), + QT_MAKE_CHECKED_ARRAY_ITERATOR(this->begin(), this->size())); return *this; } #endif @@ -467,7 +468,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA int l = int(aend - ptr); int n = l - f; if (QTypeInfo<T>::isComplex) { - std::copy(ptr + l, ptr + s, ptr + f); + std::copy(ptr + l, ptr + s, QT_MAKE_CHECKED_ARRAY_ITERATOR(ptr + f, s - f)); T *i = ptr + s; T *b = ptr + s - n; while (i != b) { @@ -489,7 +490,7 @@ bool operator==(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T, const T *rb = r.begin(); const T *b = l.begin(); const T *e = l.end(); - return std::equal(b, e, rb); + return std::equal(b, e, QT_MAKE_CHECKED_ARRAY_ITERATOR(rb, r.size())); } template <typename T, int Prealloc1, int Prealloc2> |