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