Possible bug with QList::swap. Please try to reproduce.



  • Hi guys.

    After hours and hours of debugging my rather large library, I think I've actually found the issue in Qt or the compiler optimization algorithms. Since that's a quite rare situation I'd like to present the issue here, maybe we can figure out what's happening, or at least reproduce it.

    Create a completely new Qt widgets project. Add #include <QDebug> to the header, and the following code is the MainWindow constructor:

    @MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    QList<QPointF> intersections;

    intersections = QList<QPointF>() << QPointF(1, 0) << QPointF(2, 0);
    intersections.swap(0, 1);
    qDebug() << intersections.at(0).x() << intersections.at(0).y();
    qDebug() << intersections.at(1).x() << intersections.at(1).y();
    }@

    Now hold on tight. In debug mode, this results in the output:
    @2 0
    1 0 @

    Excellent. Now release mode:
    @1 0
    1 0 @

    What?! Why are the two points identical now?
    Okay now just add qDebug << "test"; after the swap, before the other debug outputs. Now I get:
    @test
    2 0
    1 0 @

    Oh oh... When I saw that I knew it had to be something mean.

    Please tell me you can reproduce this. Any other ideas also very welcome.

    System: linux mint 3.13.0-24-generic, g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2d
    On my system this happens reproduceably with Qt 5.2.0, Qt 5.1.1, Qt 5.0.1, Qt 4.8.6, Qt 4.7.4 and Qt 4.6.4 (don't have any older versions set up but I guess it would work with them, too...)



  • Works fine with Qt 5.4.0 on Fedora 21
    @
    $ ./build-debug-Qlist_swap_bug-Desktop_Qt_5_4_0_GCC_64bit/Qlist_swap_bug
    2 0
    1 0

    $ ./build-release-Qlist_swap_bug-Desktop_Qt_5_4_0_GCC_64bit/Qlist_swap_bug
    2 0
    1 0
    @

    What compiler flags do you use for debug and for release modes?


  • Lifetime Qt Champion

    Hi,

    It's also working correctly on OS X



  • So I've tested it with Qt 5.4.0 now, too, and the phenomenon persists.

    My compiler flags are nothing peculiar:
    @g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I/usr/local/Qt-5.4.0/mkspecs/linux-g++ -I. -I/usr/local/Qt-5.4.0/include -I/usr/local/Qt-5.4.0/include/QtWidgets -I/usr/local/Qt-5.4.0/include/QtGui -I/usr/local/Qt-5.4.0/include/QtCore -I. -I. -o mainwindow.o mainwindow.cpp
    g++ -Wl,-O1 -Wl,-rpath,/usr/local/Qt-5.4.0/lib -o listswap main.o mainwindow.o moc_mainwindow.o -L/usr/local/Qt-5.4.0/lib -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread @

    I'd be very grateful for any ideas and/or tests especially on similar systems. Of course thanks alot to the two testers so far.



  • Hi,

    I was able to reproduce this on Ubuntu 14.04, g++ (Ubuntu 4.8.2-19ubuntu1)

    I also got the output
    @1
    1@

    I did another test using QString::number for the output, which worked fine.



  • Okay since it doesn't seem to be a problem with my system only, I've created a bug report:
    https://bugreports.qt-project.org/browse/QTBUG-43561



  • I've run the test on Ubuntu 14.04 with g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2 and got the same wrong result 1, 0 and 1, 0

    Then I modified code to don't use qDebug()
    @
    #include <QCoreApplication>
    #include <QPointF>
    #include <QDebug>
    #include <iostream>

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    QList<QPointF> intersections;

    intersections = QList<QPointF>() << QPointF(1, 0) << QPointF(2, 0);
    int x0 = intersections.at(0).x();
    int y0 = intersections.at(0).y();
    int x1 = intersections.at(1).x();
    int y1 = intersections.at(1).y();
    intersections.swap(0, 1);
    int x00 = intersections.at(0).x();
    int y00 = intersections.at(0).y();
    int x11 = intersections.at(1).x();
    int y11 = intersections.at(1).y();
    std::cout << "x0 = " << x0 << " y0 = " << y0 << std::endl;
    std::cout << "x1 = " << x1 << " y1 = " << y1 << std::endl;
    std::cout << "x00 = " << x00 << " y00 = " << y00 << std::endl;
    std::cout << "x11 = " << x11 << " y11 = " << y11 << std::endl;
    return 0;
    

    }
    @

    and got correct result
    @
    x0 = 1 y0 = 0
    x1 = 2 y1 = 0
    x00 = 2 y00 = 0
    x11 = 1 y11 = 0
    @

    I guess there is a bug in qDebug() with g++ 4.8.2



  • I don't think it's a bug with qDebug, because I found that behaviour in the first place in a section of (real) code where there were no debugs around. So it's not an output problem, the code really behaved as if both entries of intersections were equal...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.