Details
-
Bug
-
Resolution: Invalid
-
P2: Important
-
None
-
5.6.2
-
None
-
openSUSE Leap 42.3
gcc 4.8.5
Description
The behaviour of mixing const_iterator and iterator depend on the emptyness of the container you are walking thru. As long as the container contains elements, it seems to work, if the container is empty it crashes.
The following code works fine. Note: end() instead of cend()
#include <QtCore/qdebug.h> #include <QtCore/qstring.h> #include <QtCore/qlist.h> int main(int argc, char **argv) { QList<QString> list; list << "xx"; for(QList<QString>::const_iterator it = list.cbegin(); it != list.end(); ++ it) { qDebug() << *it; } }
But when the list is empty, the code crashes
#include <QtCore/qdebug.h> #include <QtCore/qstring.h> #include <QtCore/qlist.h> int main(int argc, char **argv) { QList<QString> list; for(QList<QString>::const_iterator it = list.cbegin(); it != list.end(); ++ it) { qDebug() << *it; } }
Same behaviour with QSet and QMap (I did not test QHash)
The problem is, that for an empty list const_iterator::cbegin() returns an object different to iterator::end() for empty containers, but an equal object for filled containers. This makes testing an application more expensive. In addition the compiler (gcc 4.8.5) does not issue a warning with all warnings (-W -Wall -Wextra) enabled.
Since you provide in the header file of QList a method
inline bool iterator::operator!=(const const_iterator &o) const Q_DECL_NOTHROW;
I expect this method to behave identical for iterators on empty and on filled containers.
Alternative solution:
define QT_STRICT_ITERATORS to prevent such a mix of iterators
Add some code like #warning or #pragma warning(...) to the code.