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
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development