I was running into problems in release mode in some threaded code and narrowed down the problem to the following lines.
Qt Code:
  1. QFutureWatcher<Result> watcher;
  2. QList<Job> jobs;
  3. ...
  4. if(jobs.isEmpty() || watcher.isStarted() && !watcher.isFinished())
  5. return;
  6. watcher.setFuture(QtConcurrent::run(..., jobs.takeFirst()));
To copy to clipboard, switch view to plain text mode 
The problem is that the first time this code is run(watcher is only default constructed) the expression "watcher.isStarted() && !watcher.isFinished()" evaluates to true, but only in release mode.

After sifting through some code I found out that the trolls decided that a default constructed QFuture is supposed to have the states Started | Finished | Canceled, which might be a bit counter-intuitive, but is fine by me.

The problem is that the following program:
Qt Code:
  1. #include <QDebug>
  2. #include <QFutureWatcher>
  3.  
  4. int main()
  5. {
  6. QFutureWatcher<int> watcher;
  7. qDebug()<<"isStarted()"<<watcher.isStarted();
  8. qDebug()<<"isFinished()"<<watcher.isFinished();
  9. qDebug()<<"isCanceled()"<<watcher.isCanceled();
  10. return 1;
  11. }
To copy to clipboard, switch view to plain text mode 
gives the following output in release mode:
Qt Code:
  1. isStarted() true
  2. isFinished() false
  3. isCanceled() true
To copy to clipboard, switch view to plain text mode 
whereas if you exchange QFutureWatcher with QFuture it gives the expected output.

I have tried it with MSVC 2008 and Qt 4.6.2 and would like to here if anyone can confirm this, or even better explain how it can happen.