Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-8967

QT_REQUIRE_VERSION causes a warning due to passing a non-string literal to qFatal (ReOpen)

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P3: Somewhat important
    • 4.7.0
    • 4.6.2
    • Other
    • None
    • Gentoo, gcc 4.4.3, x86-64, kernel 2.6.31
    • 814f7d3d607edacca091273302297b6b2674424f

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

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            goffart Olivier Goffart (closed Nokia identity) (Inactive)
            eteran Evan Teran
            Votes:
            2 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes