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

Document QStringBuilder's auto gotcha

XMLWordPrintable

      We need to document that assigning QStringBuilder expressions to auto variables or returning QStringBuilder expressions from functions with deduced return types (in particular, lambdas) doesn't work. This was the original report:

      Usages of QStringBuilder seem to raise `std::bad_alloc` when used in the reducer of `std::transform_reduce`. For example, the following: 

      #define QT_USE_QSTRINGBUILDER 1
      
      #include <QString>
      #include <QStringList>
      
      int main(int argc, char *argv[])
      {
      	QStringList a{"abv", "def"};
      	std::transform_reduce(
                  a.begin(),
                  a.end(),
                  QString{},
                  [](QString accumulator, QString element) { return accumulator + ", " + element; },
                  [](auto a){ return a; }
      	).toStdString();
      }
      

      Reports, when executed:

      terminate called after throwing an instance of 'std::bad_alloc'
        what():  std::bad_alloc
      fish: Job 1, 'build/exampleme' terminated by signal SIGABRT (Abort)
      

      Disabling QStringBuilder removes the issue and completes the call correctly.

      Similarly, specifying the return type of the reducer as `QString` or casting/constructing to `QString` in the reducer will remove the issue, such that all of the following complete correctly:

                  [](QString accumulator, QString element) -> QString { return accumulator + ", " + element; },
      
                  [](QString accumulator, QString element) { return QString{accumulator + ", " + element}; },
      
                  [](QString accumulator, QString element) { return (QString)(accumulator + ", " + element); },
      
                  [](QString accumulator, QString element) { return static_cast<QString>(accumulator + ", " + element); },
      

      Removing the middle element will solve the issue too:

                  [](QString accumulator, QString element) { return accumulator + element; },
      

      But making it a `QString` will instead fail with a SIGSEGV:

                  [](QString accumulator, QString element) { return accumulator + QString{", "} + element; },
      
      fish: Job 1, 'build/exampleme' terminated by signal SIGSEGV (Address boundary error)
      

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

            docteam Qt Documentation Team
            diseraluca Luca Di Sera
            Vladimir Minenko Vladimir Minenko
            Alex Blasche Alex Blasche
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes