c++stringqtqstring

Building QString out string


With the following piece of code:

QString msg;
msg =   "Datalogging Item"          + ',' +
        QString::number(item)       + ',' +
        "Slave Index"               + ',' +
        QString::number(slaveIndex) + ',' +
        "Slave Name"                + ',' +
        slaveName                   + ',' +
        "Experiment Index"          + ',' +
        QString::number(expIndex)   + ',' +
        "Experiment Name"           + ',' +
        expName                     + ',' +
        "Aquisition Frequency "     + ',' +
        "33 Hz"                     + "\n";
qDebug() << msg;

I was getting the following debug output

"riment Index0,Slave Index,0,Slave Name,Execute 1,Experiment Index,0,Experiment Name,Read All (Barebone),Aquisition Frequency ,33 Hz\n"

Which is not really what I was expected to get.

But with the code modified with the QString typecast:

QString msg;
msg =   QString("Datalogging Item")     + QString(',') +
        QString::number(item)           + QString(',') +
        QString("Slave Index")          + QString(',') +
        QString::number(slaveIndex)     + QString(',') +
        QString("Slave Name")           + QString(',') +
        slaveName                       + QString(',') +
        QString("Experiment Index")     + QString(',') +
        QString::number(expIndex)       + QString(',') +
        QString("Experiment Name")      + QString(',') +
        expName                         + QString(',') +
        QString("Aquisition Frequency ")+ QString(',') +
        QString("33 Hz")                + QString("\n");
qDebug() << msg;

I get what I expected to get:

"Datalogging Item,0,Slave Index,0,Slave Name,Execute 1,Experiment Index,0,Experiment Name,Read All (Barebone),Aquisition Frequency ,33 Hz\n"

Do you have any clue on what is going on? I just don't get what is going on and I'm a newbie to QT.

Thanks.


Solution

  • The expression

    "Datalogging Item" + ','
    

    has the type and meaning of

    static_cast<const char *>("Datalogging Item" + 44)
    

    You're taking the address of the beginning of the Datalogging string constant and adding 44 to it - advancing it by 44 characters. This is undefined behavior as you're moving a pointer past the object it points to. By coincidence the pointer happens to point to another C string constant.

    A short program that reproduces the issue:

    #include <iostream>
    int main() {
      std::cout << "Datalogging Item Foo Bar Baz" + '\n' << std::endl;
    }
    

    Output:

    g Item Foo Bar Baz
    

    One way of rewriting your expression to make it valid and less verbose would be to use the arg-substitution mechanism of QString:

    auto msg = QStringLiteral(
      "Datalogging Item,%1,Slave Index,%2,Slave Name,%3,Experiment Index,%4,"
      "Experiment Name,%5,Acquisition Frequency,%6\n")
       .arg(item).arg(slaveIndex).arg(slaveName).arg(expIndex)
       .arg(expName).arg(QStringLiteral("33 Hz"));
    

    If you're using Qt 4, replace QStringLiteral with QString::fromUtf8. The QStringLiteral is a mechanism introduced in Qt 5 that builds up a constant QString instance at compile time, yielding smaller code and better runtime performance than the use of a QString constructor.