Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Missing increment of index in foreach with QMap
Forum Updated to NodeBB v4.3 + New Features

Missing increment of index in foreach with QMap

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 3 Posters 257 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    EMStegehuis
    wrote on 21 Apr 2020, 11:24 last edited by EMStegehuis
    #1

    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)
    
    K 1 Reply Last reply 21 Apr 2020, 23:03
    0
    • E Offline
      E Offline
      EMStegehuis
      wrote on 21 Apr 2020, 11:26 last edited by EMStegehuis
      #2

      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.

      1 Reply Last reply
      0
      • C Offline
        C Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on 21 Apr 2020, 15:43 last edited by Christian Ehrlicher
        #3

        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();
        }
        

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        2
        • E EMStegehuis
          21 Apr 2020, 11:24

          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)
          
          K Offline
          K Offline
          kshegunov
          Moderators
          wrote on 21 Apr 2020, 23:03 last edited by
          #4

          @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.

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          2

          1/4

          21 Apr 2020, 11:24

          • Login

          • Login or register to search.
          1 out of 4
          • First post
            1/4
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved