Reputation: 23
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.
Upvotes: 0
Views: 1100
Reputation: 98505
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.
Upvotes: 1
Reputation: 2232
It is better to use QStringLiteral macro for static string in code.
msg = QStringLiteral("Datalogging Item") + ',' +
More info here: http://doc.qt.io/qt-5/qstring.html#QStringLiteral
Upvotes: 0
Reputation: 104589
You can repro similar results even simpler:
msg = "Datalogging Item" + ',' + QString::number(item);
And now it occurs to be exactly what the issue is. The first part of that expression is simply:
"Datalogging Item" + ','
In the above expression, a raw string literal is having the integer value of 44 (ascii val for comma) added to it's pointer address. Hence, you are now in "undefined" territory since the length of "Datalogging Item"
is far less than 44 characters. Most likely what's happening is that the above expression is now a pointer expression into the middle of one of your other string literals defined nearby.
The solution is simply to declare the first element to be a QString so that all subsequent "additions" will use the overloaded +
operator of QString:
msg = QString("Datalogging Item") + ',' +
QString::number(item) + ',' +
...
Upvotes: 3