Missing increment of index in foreach with QMap
-
Hello,
Since we updated from VS 16.3.10 to 16.5.4 we had some failures in our unittest. We were able to track them down to an old usage of QMap in a foreach.
In the example code below the rowNr variable is not incremented at all in release mode. In debug it is. Optimisation level is set to /O2.
When yo uncomment the last logging line the counter is incremented.
Has anybody a clue whether this is a bug in Qt?
The funny thing is ist does not happen with the stringlist so it has something to do with the foreach + QMap.
And yes: There are better ways to iterate over a QMap.
QMap <QString, QString> mapContainer; mapContainer.insert (QString ("One"), QString ("1")); mapContainer.insert (QString ("Two"), QString ("2")); mapContainer.insert (QString ("Three"), QString ("3")); mapContainer.insert (QString ("Four"), QString ("4")); mapContainer.insert (QString ("Five"), QString ("5")); //QStringList mapContainer = { QString ("One"), QString ("Two"), QString ("Three"), QString ("Four"), QString ("Five") }; unsigned int rowNr = 0; foreach (QString contour, mapContainer) //for (unsigned int secondLoopIndex = 0; secondLoopIndex < 5; ++secondLoopIndex) { LOGINFO (QString ("<-----------------------Index row in loop before incr.: (%1)").arg (rowNr)); ++rowNr; //LOGINFO (QString ("<-----------------------Index row in loop after incr.: (%1)").arg (rowNr)); }
Output
<-----------------------Index row in loop before incr.: (0) <-----------------------Index row in loop before incr.: (0) <-----------------------Index row in loop before incr.: (0) <-----------------------Index row in loop before incr.: (0) <-----------------------Index row in loop before incr.: (0)
-
And it helps to not put the increment (++rowNr) at the end of the for loop (without direct usage) but at the beginning prior to its usage.
So it seems related to some optimisation.
-
Please provide a minimal compilable example so we can test you code. This code is working fine:
int main(int argc, char **argv) { QApplication app(argc, argv); QMap <QString, QString> mapContainer; mapContainer.insert (QString ("One"), QString ("1")); mapContainer.insert (QString ("Two"), QString ("2")); mapContainer.insert (QString ("Three"), QString ("3")); mapContainer.insert (QString ("Four"), QString ("4")); mapContainer.insert (QString ("Five"), QString ("5")); unsigned int rowNr = 0; foreach (QString contour, mapContainer) //for (unsigned int secondLoopIndex = 0; secondLoopIndex < 5; ++secondLoopIndex) { qDebug() << QString ("<-----------------------Index row in loop before incr.: (%1)").arg (rowNr); ++rowNr; qDebug() << QString ("<-----------------------Index row in loop after incr.: (%1)").arg (rowNr); } return app.exec(); }
-
@EMStegehuis said in Missing increment of index in foreach with QMap:
Has anybody a clue whether this is a bug in Qt?
Probably not. Compile in release with debug info and inspect the assembly, probably an optimizer problem. Whatever the reason, however, you should move to a range-based
for
,foreach
's deprecated.