[Development] Could support for C be added to Qt?

samuel ammonius sfammonius at gmail.com
Sat Sep 10 19:02:05 CEST 2022

> Allan’s proposal to keep the code C but ensure it builds with a C++
> compiler likely had precisely this kind of scenario in mind. It does
> help others to make a generic interface. It is likely a lot more work.
> Experience with an AI-assisted IDE could speed things.

> And what's the gain here? What does one gain from compiling as C, instead
> using the C++ compiler that comes with the same suite?

There are some subtle differences between the two languages that can make
converting between them a huge pain. For example, C-like casts don't work
half the time in C++ so you have to use static_cast(), and void* isn't
with other pointer types, so the return of malloc() has to be casted pretty
every time it's used. These may not seem like huge issues, but the fact
that the
language has no problem with anything that the actual computer doesn't have
problem with is something very valuable for most C developers, so they
won't want to switch.

> I don't see how a binding could
> be automated to C. It would require manual intervention for every
> function, of which there are many.

In the qtc project I linked to earlier, I managed to implement function
in C using vardiac macro functions that would find the number of parameters
add that number to the end of the function. For example, QPushButton() would
become QPushButton0(), and QPushButton(QString("hello")) would become
QPushButton1(QString("hello")). For overloaded functions with the same
of parameters, I used the _Generic keyword to find the right function using
parameter's type. Here
<https://github.com/sammonius/qtc/blob/main/header/qpushbutton.h>'s one
example (QPushButton_new(), lines 12-21).

I don't think it will be hard to add C support anyways, and I think I might
a solution to the constructor/destructor issue: another pair of macros
wrappers for new and delete:

#ifdef __cplusplus
#    define QT_C_OBJECT_EXPORT(OBJ, PARAMS) OBJ * new_##OBJ PARAMS ; void
delete_##OBJ ();
#    define QT_C_OBJECT_EXPORT(OBJ, PARAMS) typedef struct OBJ OBJ ; OBJ *
new_##OBJ PARAMS ; void delete_##OBJ ();

{return new OBJ PARAMS ;} void delete_##OBJ (){ delete OBJ ;}

They take a parameter for the object's name and the parameters for its
constructor. Their usage is really simple:
QT_C_EXPORT_OBJECT(QPushButton, (QIcon *icon, QString text, QWidget

QT_DEFINE_C_EXPORT_OBJECT(QPushButton, (QIcon *icon, QString text, QWidget

Also, most of Qt's template functions and classes
(including QObject::connect and disconnect) are only templated in the
declaration to prevent type-errors. Those errors would only be warnings in
C, and they can be silenced completely using something like this:

void QObject_connect_p(QObject *sender, void *signal, QObject *reciever,
void *slot);
#define QObject_connect(A, B, C, D) QObject_connect(A, (void*)B, C,

(I'm only using QObject::connect as a general example, but this probably
isn't how it would look since we would want a compile-time error for the
signal and slot being of different types like Qt does in C++)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20220910/657a8952/attachment.htm>

More information about the Development mailing list