Details
Description
I recently submitted bug #8547 (http://bugreports.qt.nokia.com/browse/QTBUG-8547) which was resolved as "invalid" but unfortunately the solution provided does not work.
The following code causes a warning :
#include <QApplication> #include <QMessageBox> // Why is QT_REQUIRE_VERSION found here instead // of QtGlobal as documented? #include <QtGlobal> int main(int argc, char *argv[]) { QT_REQUIRE_VERSION(argc, argv, "4.5.0"); QApplication app(argc, argv); return app.exec(); }
test.cc: In function 'int main(int, char**)':
test.cc:7: warning: format not a string literal and no format arguments
Note: I've added a semicolon as recommended by the previous bugs resolution. Which did change the warning's line number to 7 from 8. But the warning still stands. The compile flags used where the following:
g++ -c -pipe -march=native -fomit-frame-pointer -O3 -pipe -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -o test.o test.cc
Also the documentation fails to put a semicolon after the macro.
I've looked at the code for QT_REQUIRE_VERSION and the issue is the very last statement of the maco:
#define QT_REQUIRE_VERSION(argc, argv, str) { QString s = QString::fromLatin1(str);\ QString sq = QString::fromLatin1(qVersion()); \ if ((sq.section(QChar::fromLatin1('.'),0,0).toInt()<<16)+\ (sq.section(QChar::fromLatin1('.'),1,1).toInt()<<8)+\ sq.section(QChar::fromLatin1('.'),2,2).toInt()<(s.section(QChar::fromLatin1('.'),0,0).toInt()<<16)+\ (s.section(QChar::fromLatin1('.'),1,1).toInt()<<8)+\ s.section(QChar::fromLatin1('.'),2,2).toInt()) { \ if (!qApp){ \ new QApplication(argc,argv); \ } \ QString s = QApplication::tr("Executable '%1' requires Qt "\ "%2, found Qt %3.").arg(qAppName()).arg(QString::fromLatin1(\ str)).arg(QString::fromLatin1(qVersion())); QMessageBox::critical(0, QApplication::tr(\ "Incompatible Qt Library Error"), s, QMessageBox::Abort, 0); qFatal(s.toLatin1().data()); }}
Note this part:
qFatal(s.toLatin1().data());
qFatal is defined as follows:
Q_CORE_EXPORT void qFatal(const char *, ...) /* print fatal message and exit */ #if defined(Q_CC_GNU) && !defined(__INSURE__) __attribute__ ((format (printf, 1, 2))) #endif ;
so for gcc system it has the printf attribute, meaning that a non-string literal for the first parameter is considered bad... It seems to be that the solution would be the change that last part to something like this:
qFatal("%s", s.toLatin1().data());
You get the same functionality, but no format string warning (or even possible errors if misused).