[Development] A QStringList puzzle for Monday

Mathias Hasselmann mathias at taschenorakel.de
Mon Mar 17 21:39:42 CET 2025


I really want to highlight Igors advice to define QT_NO_CAST_FROM_ASCII. 
It really removes countless traps when using Qt, and will give you a 
much more pleasant experience.

To avoid bloating you code with QString{}, QStringLiteral{} or 
QLatin1String{} boilerplate after enabling QT_NO_CAST_FROM_ASCII you 
also might consider using UTF-16 string literals (u"your text") and you 
might want to use the Qt::StringLiterals namespace.

Ciao
Mathias

Am 17.03.25 um 20:27 schrieb Henry Skoglund:
> Thanks for your answers! So it's a lethal combo of string literals and 
> iterators, something to keep in mind when writing C++.
> Rgrds Henry
>
>
> n 2025-03-17 20:09, Jøger Hansegård wrote:
>>> Obviously I am doing something wrong when setting o4 but it would be 
>>> nice if I could get a compile error...
>> Hi Henry,
>>
>> Yes, this recently confused me as well, and here is what I found:
>>
>> The issue is that QStringList("g","goessouth") behaves the same way 
>> as std::vector<QString>(“g","goessouth"). In both cases, the string 
>> literals collapse to pointers, and we call the QStringList(InputIt 
>> first, InputIt last) overload. The result will likely be a buffer 
>> overrun and possibly a crash. If you use the curly braces to 
>> initialize with an initializer list, the code does what you expect.
>>
>> I agree that it would be nice to have a compiler error but given that 
>> QStringList behaves the same way as std::vector, I am not sure it is 
>> a bug.
>>
>> Best regards,
>> Jøger
>
>
> On 2025-03-17 20:08, Igor Khanin wrote:
>> Hi,
>>
>> This is a really unfortunate (and all too common) case...
>>
>> o4 is invoking the QList(InputIterator, InputIterator) constructor, 
>> with the `InputIterator` type being deduced as `const char *`. This 
>> is a valid iterator type with traits specialization and everything, 
>> so this constructor is a member of the overload set. As long as there 
>> is a implicit conversion path from `const char` to `QString`, it will 
>> compile... and there is such a path. Of course trying to do pointer 
>> arithmetic on pointers to string literals is UB. The only way I see 
>> to make it not compile is to remove the conversion path by defining 
>> QT_NO_CAST_FROM_ASCII.
>>
>> I'm not sure that anything can be added on top of the 
>> meta-programming already in QList to stop this. This is also 
>> something you can run into with a `std::vector<std::string>`. Just 
>> one more data point to how the prevalent use of iterator pairs is 
>> another footgun in C++'s arsenal.
>>
>> Igor
>>
>> On 17/03/2025 20:32, Henry Skoglund wrote:
>>> Hello, there are a more than one way to initialize a QStringList but 
>>> sometimes they are not equal, consider this console app:
>>>
>>> main.cpp:
>>> #include <QCoreApplication>
>>> #include "qcommandlineparser.h"
>>> #include "qdebug.h"
>>>
>>> int main(int argc, char *argv[])
>>> {
>>>     QCoreApplication a(argc, argv);
>>>
>>>     QCommandLineParser lp;
>>>     QCommandLineOption o1(QStringList() << "o" << "ok");
>>>     QCommandLineOption o2(QStringList{"a","alsook"});
>>>     QCommandLineOption o3(QStringList("yesok"));
>>>     qDebug() << "geronimo";
>>>     QCommandLineOption o4(QStringList("g","goessouth"));
>>>     qDebug() << "landed";
>>>
>>>     lp.addOptions({o1,o2,o3,o4});
>>> }
>>>
>>> If I build it in debug mode on 6.8.2, either with MSVC 2022 or gcc 
>>> version 13.3.0 on Ubuntu and run it:
>>>
>>> 18:57:31: Starting 
>>> /home/henry/untitled/build/Desktop_Qt_6_8_2-Debug/untitled...
>>> geronimo
>>> ASSERT: "this->isMutable() || b == e" in file 
>>> /home/henry/Qt/6.8.2/gcc_64/include/QtCore/qarraydataops.h, line 884
>>> 18:57:32: The process crashed.
>>>
>>> In release mode:
>>> 19:12:47: Starting 
>>> /home/henry/untitled/build/Desktop_Qt_6_8_2-Release/untitled...
>>> geronimo
>>> landed
>>> QCommandLineParser: already having an option named "a"
>>> 19:12:47: 
>>> /home/henry/untitled/build/Desktop_Qt_6_8_2-Release/untitled exited 
>>> with code 0
>>>
>>>
>>> Obviously I am doing something wrong when setting o4 but it would be 
>>> nice if I could get a compile error...
>>>
>>> Rgrds Henry
>>>
>>>
>


More information about the Development mailing list