3

I am playing with cppfront (https://github.com/hsutter/cppfront), a possible C++ successor, in combination with Qt. I am trying to replicate the simplest possible widget application showing just an empty widget.

In C++ (aka cpp1) it would be like this:

#include <QApplication>
#include <QWidget>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget w;
    w.show();
    return a.exec();
}

In cppfront (aka cpp2) I am trying this:

#include <QApplication>
#include <QWidget>

main: (args) -> int =
{
    app := QApplication(args.argc, args.argv);
    w := QWidget();
    w.show();
    return app.exec();
}

I build it first with cppfront and then with MSVC. It results in errors like error: C2440: '<function-style-cast>': cannot convert from 'initializer list' to 'QApplication'. After more trial and error I found out that the problem is that args.argv is char const* const* while QApplication expects char** as the second argument. Just to prove this I tried this:

main: (args) -> int =
{
    app := QApplication(args.argc, nullptr);
    ...

Then the constructor types match well and the program builds and runs fine. Of course it is not correct because it does not pass the arguments. So I tried this:

main: (args) -> int =
{
    app := QApplication(args.argc, std::const_cast<char**>(args.argv));
    ...

But then cppfront complains: error: 'const_cast' is not supported in Cpp2 - the current C++ best practice is to never cast away const, and that is const_cast's only effective use. I fully understand this is for memory safety reasons to prevent possible programming errors.

So my question is: has anyone any simple solution to instantiate a QApplication with passing arguments correctly in vanilla cppfront?

PS: I am using qmake build with pro file:

QT = core gui widgets

CONFIG += c++20

SOURCES += \
        main.cpp

OTHER_FILES += \
        main.cpp2

INCLUDEPATH += C:\cppfront\include

of course you would need to change the cppfront include path to match your paths. I am compiling cpp2 to cpp manually with just cppfront main.cpp in the command line. So no fancy pre-build steps in qmake yet because I am still just experimenting... What is important in this file is c++20 flag and that include path. I am using Qt6.5.2.

1 Answers1

1

VERSION 1 (not working):

So after a few more trials and errors (you know, there is still no official documentation to cppfront available at the moment of writing this) I found this possibility:

#include <QApplication>
#include <QWidget>

main: (args) -> int =
{
    app := QApplication(args.argc, args.argv as **char); // note the position of **, that's a gotcha for for someone coming from C/C++
    w := QWidget();
    w.show();
    return app.exec();
}

It builds with cppfront with MSVC and runs well. But it does not compile with clang. It shows error error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<char **, const char *const *>' "No safe 'as' cast available - please check your cast"

VERSION 2 (working as of 2023-08-16):

I posted query to project page https://github.com/hsutter/cppfront/issues/592 and the author reacted and changed args.argv member to char**. So the original code app := QApplication(args.argc, args.argv); now should work fine. Btw. args.argv remains for compatibility with C++. The new and safer way of working with arg is the fact that args inherits from std::vector<std::string_view> which provides more modern and safer way of working with args. This should be recommended to be used in cppfront code.

PS: Please note that cppfront project is still evolving and is just an experiment. Many things can change yet. Let's see how well it work together with Qt framework.