What my verdigris experience shows is that it is perfectly possible to replace the moc at the cost of slightly uglier macros. And this was using C++14.
I haven't look in details at the C++26 reflection, but I'm sure it would make it easier to make these macro more pretty.
Even if C++26 covers all scenarios needed for MOC, it is going to take ages until Qt can rely on it being available across all their customer platforms, unfortunely after a spike in the last decades regarding ISO C++ support, the compilers velocity has slowed down, while proprietary compilers have decided to freeze their support somewhere between C++14 and C++17.
Most likely the raise of AOT compiled alternatives, for scenarios where C and C++ were only being used due to being compiled languages, big names in C++ compiler world rather put money on their own alternatives, are the two main reasons of the slow down.
> Most likely the raise of AOT compiled alternatives, for scenarios where C and C++ were only being used due to being compiled languages, big names in C++ compiler world rather put money on their own alternatives, are the two main reasons of the slow down.
What alternatives?
Rust claws at market share but has problems with basic stuff like doubly linked lists, WIP gccrs and memory unsafety,
Carbon looks like a meme with too few people working on it,
Ada has a neglected dialect and a proprietary dialect,
Go has garbage collection,
Zig has not even reached 1.0,
Swift is more of an application language than a systems language,
Circle is dead.
> Rust claws at market share but has problems with basic stuff like doubly linked lists, WIP gccrs and memory unsafety,
Doubly linked lists aren’t that important today. Rust doesn’t need gccrs to be useful, and it gives much better memory safety than C++ without needing a GC. So I find your criticism of Rust seems a bit weak. Rust is a strong alternative to C++.
Many people that use C and C++, do it out of habit, any compiled language, even with AOT is capable to deliver for most scenarios in userspace code.
99% of user software written in compiled languages isn't systems programming juggling pointers and type casts.
Even when that is the case, all above languages have FFI features, no need to rewrite the whole thing.
You might have noticed that C and C++ are minority languages in the mobile OS duopoly, for starters, being used only for low level OS services, and game engines.
Where are you seeing proprietary compilers freezing support after C++17. C++20 support is almost green across the board (even Cray) and C++23 is getting there. As usual there is a lag, for ex. when nvcc will declare C++23 support and whole swath will turn green. Right now it only supports C++20 (but you can mix in C++23 files and link them together) etc.. I see most C++ projects make C++20 a minimum. (not counting someone who wants to keep running C++98).
Easy, go hunting their manuals for the compilers that aren't yet another clang fork, still a few around between TI, Microchip and co on embedded.
In general, not for Qt deployment scenarios, also take into consideration the surviving big iron UNIX, mainframes and micros still in business, again the compilers that are yet not clang forks.
The table is a non exaustive overview, however it also paints the picture that for those that care about real portable code, regular visits to the table are required before considering adopting any specific new feature, or the need to enforce style guides like "we use C++20, but feature X, Y, Z are forbidden due to lack of portablity".
I used to use Qt quite extensively years ago, and it seemed that all MOC was really bringing to the table was signal-slot connections which can certainly be done in much nicer ways (e.g. just use std::function to represent signals).
> I used to use Qt quite extensively years ago, and it seemed that all MOC was really bringing to the table was signal-slot connections which can certainly be done in much nicer ways (e.g. just use std::function to represent signals).
The linked article goes into detail on what are the use cases for MOC and what are the shortcomings of C++26 to completely replace MOC with C++ reflections.
If you read the article, the goal they are aiming for is replacing MOC with C++ reflections without requiring fundamental changes to how Qt works. There are many reputable and very stable signal&slots implementations in C++ that are both type safe and do not require reflection at all. Some of these projects exist for over a decade already, and required only C++14. But Qt's implementations of signals and slots require far more than that to have a drop-in replacement.
If you use QML it does, like... everything? QML can't interact with native C++ at all, you must use the MOC to generate Q_PROPERTYs, signal/slots, the Q_OBJECT macro itself etc.
Meanwhile, copperspice got rid of the MOC more than 10 years ago.
I'm no longer familiar with Qt nor C++, but I guess the real blocker here is that the Qt foundation is only looking for ways that are 100% backward-compatible to inccur no change in its commercial userbase? Or am I missing something more subtle?
> looking for ways that are 100% backward-compatible to inccur no change in its commercial userbase?
Non-commercial users also care about backwards compatibility.
Also FWIW Qt does break backwards compatibility in major versions, though the breakage isn't huge. And regardless of commercial or non-commercial, it is in general a good idea to avoid breaking people's working code.
> Meanwhile, copperspice got rid of the MOC more than 10 years ago.
That's perfectly fine. Copperspice didn't aimed to support legacy code, and thus could introduce backwards incompatible changes without looking back.
Dropping support for legacy Qt code also ensured it was automatically irrelevant, which is why most people in a thread over Qt have absolutely no idea what copperspice is, let alone that it existed for over a decade.
I wasn't aware of Copperspice, but would have been tempted to use it. Qt seemed to have lost it's way when it started with Qt Quick and QML and deemphasized it's roots as a cross-platform library with widget-based UI.
I was always uncomfortable with MOC - the rest of Qt was great, so you put up with MOC, but I was always hoping they might have moved away from it as C++ got more powerful.
What exactly are your qualms with Qt Quick and QML? I find the separation of UI (QML) and logic (C++) pretty amazing. QML is such a nice language and the framework has grown a lot over the years. I developed a block editor (Notion style) in QML and C++, wrote about it in my blog[1].
I was always kind of uncomfortable with MOC too, but I couldn't really articulate why. I consider it "wizardry that works but I don't understand" and I never bothered to go in and really understand it. The more I program though, the less I want any kind of "wizardry" in my code, whether or not I understand it.
Does this motivate me to go back into all my C++/Qt projects and try to un-MOC-ify them? No. But if I started a new project, maybe I'd try to do with without MOC and instead do more in handwritten C++ code.
Moc is complex. reflection is complex. round one was trying to be as simple as possible while still allowing some real world use and allow room for the future.
10 years ago, in another life, I was already experimenting with trying to provides feature from moc with reflections and from other macros:
- https://woboq.com/blog/reflection-in-cpp-and-qt-moc.html 2014, That was based on a previous reflection proposal
- https://github.com/woboq/verdigris : 2016, Replaces the moc by a set of macros.
What my verdigris experience shows is that it is perfectly possible to replace the moc at the cost of slightly uglier macros. And this was using C++14. I haven't look in details at the C++26 reflection, but I'm sure it would make it easier to make these macro more pretty.
Even if C++26 covers all scenarios needed for MOC, it is going to take ages until Qt can rely on it being available across all their customer platforms, unfortunely after a spike in the last decades regarding ISO C++ support, the compilers velocity has slowed down, while proprietary compilers have decided to freeze their support somewhere between C++14 and C++17.
Most likely the raise of AOT compiled alternatives, for scenarios where C and C++ were only being used due to being compiled languages, big names in C++ compiler world rather put money on their own alternatives, are the two main reasons of the slow down.
- https://en.cppreference.com/w/cpp/compiler_support.html
- https://en.cppreference.com/w/cpp/compiler_support/17.html
- https://en.cppreference.com/w/cpp/compiler_support/14.html
> Most likely the raise of AOT compiled alternatives, for scenarios where C and C++ were only being used due to being compiled languages, big names in C++ compiler world rather put money on their own alternatives, are the two main reasons of the slow down.
What alternatives?
Rust claws at market share but has problems with basic stuff like doubly linked lists, WIP gccrs and memory unsafety, Carbon looks like a meme with too few people working on it, Ada has a neglected dialect and a proprietary dialect, Go has garbage collection, Zig has not even reached 1.0, Swift is more of an application language than a systems language, Circle is dead.
What else is there?
Not that C++ doesn't have challenges.
> Rust claws at market share but has problems with basic stuff like doubly linked lists, WIP gccrs and memory unsafety,
Doubly linked lists aren’t that important today. Rust doesn’t need gccrs to be useful, and it gives much better memory safety than C++ without needing a GC. So I find your criticism of Rust seems a bit weak. Rust is a strong alternative to C++.
3 replies →
Go, Java (GraalVM/OpenJ9), .NET (Native AOT, .NET Native, IL2CPP, Mono AOT), Swift, Objective-C, D, Nim, Ada.
Many people that use C and C++, do it out of habit, any compiled language, even with AOT is capable to deliver for most scenarios in userspace code.
99% of user software written in compiled languages isn't systems programming juggling pointers and type casts.
Even when that is the case, all above languages have FFI features, no need to rewrite the whole thing.
You might have noticed that C and C++ are minority languages in the mobile OS duopoly, for starters, being used only for low level OS services, and game engines.
1 reply →
>Ada has a neglected dialect and a proprietary dialect
What on earth are you on about? That’s not the case.
Ada 2022 has been released and Ada 202x is getting improvements. Those features are trickling into FSF GNAT (GCC).
Are you talking about the SPARK dialect, where GNATprove is open source?
1 reply →
as for rust linked list
https://crates.io/crates/ghost-cell
1 reply →
> What else is there?
There’s Nim, which is getting a major overhaul for v3 (cf. Nimony).
Where are you seeing proprietary compilers freezing support after C++17. C++20 support is almost green across the board (even Cray) and C++23 is getting there. As usual there is a lag, for ex. when nvcc will declare C++23 support and whole swath will turn green. Right now it only supports C++20 (but you can mix in C++23 files and link them together) etc.. I see most C++ projects make C++20 a minimum. (not counting someone who wants to keep running C++98).
Easy, go hunting their manuals for the compilers that aren't yet another clang fork, still a few around between TI, Microchip and co on embedded.
In general, not for Qt deployment scenarios, also take into consideration the surviving big iron UNIX, mainframes and micros still in business, again the compilers that are yet not clang forks.
The table is a non exaustive overview, however it also paints the picture that for those that care about real portable code, regular visits to the table are required before considering adopting any specific new feature, or the need to enforce style guides like "we use C++20, but feature X, Y, Z are forbidden due to lack of portablity".
1 reply →
What are all the use cases for MOC?
I used to use Qt quite extensively years ago, and it seemed that all MOC was really bringing to the table was signal-slot connections which can certainly be done in much nicer ways (e.g. just use std::function to represent signals).
> I used to use Qt quite extensively years ago, and it seemed that all MOC was really bringing to the table was signal-slot connections which can certainly be done in much nicer ways (e.g. just use std::function to represent signals).
The linked article goes into detail on what are the use cases for MOC and what are the shortcomings of C++26 to completely replace MOC with C++ reflections.
If you read the article, the goal they are aiming for is replacing MOC with C++ reflections without requiring fundamental changes to how Qt works. There are many reputable and very stable signal&slots implementations in C++ that are both type safe and do not require reflection at all. Some of these projects exist for over a decade already, and required only C++14. But Qt's implementations of signals and slots require far more than that to have a drop-in replacement.
That is what the linked article is about: what moc provides and what the pure C++ equivalent (if any) could be.
If you use QML it does, like... everything? QML can't interact with native C++ at all, you must use the MOC to generate Q_PROPERTYs, signal/slots, the Q_OBJECT macro itself etc.
Meanwhile, copperspice got rid of the MOC more than 10 years ago.
I'm no longer familiar with Qt nor C++, but I guess the real blocker here is that the Qt foundation is only looking for ways that are 100% backward-compatible to inccur no change in its commercial userbase? Or am I missing something more subtle?
> looking for ways that are 100% backward-compatible to inccur no change in its commercial userbase?
Non-commercial users also care about backwards compatibility.
Also FWIW Qt does break backwards compatibility in major versions, though the breakage isn't huge. And regardless of commercial or non-commercial, it is in general a good idea to avoid breaking people's working code.
> Meanwhile, copperspice got rid of the MOC more than 10 years ago.
That's perfectly fine. Copperspice didn't aimed to support legacy code, and thus could introduce backwards incompatible changes without looking back.
Dropping support for legacy Qt code also ensured it was automatically irrelevant, which is why most people in a thread over Qt have absolutely no idea what copperspice is, let alone that it existed for over a decade.
I wasn't aware of Copperspice, but would have been tempted to use it. Qt seemed to have lost it's way when it started with Qt Quick and QML and deemphasized it's roots as a cross-platform library with widget-based UI.
I was always uncomfortable with MOC - the rest of Qt was great, so you put up with MOC, but I was always hoping they might have moved away from it as C++ got more powerful.
What exactly are your qualms with Qt Quick and QML? I find the separation of UI (QML) and logic (C++) pretty amazing. QML is such a nice language and the framework has grown a lot over the years. I developed a block editor (Notion style) in QML and C++, wrote about it in my blog[1].
[1] https://rubymamistvalove.com/block-editor
3 replies →
I was always kind of uncomfortable with MOC too, but I couldn't really articulate why. I consider it "wizardry that works but I don't understand" and I never bothered to go in and really understand it. The more I program though, the less I want any kind of "wizardry" in my code, whether or not I understand it.
Does this motivate me to go back into all my C++/Qt projects and try to un-MOC-ify them? No. But if I started a new project, maybe I'd try to do with without MOC and instead do more in handwritten C++ code.
1 reply →
Like most forks, it seldom gets used by the large majority that still cares about Qt.
It also never supported the whole Qt tooling ecosystem.
Related issue https://bugreports.qt.io/browse/QTBUG-140912
Comment in the issue referring to the wiki page: "note: it needs updates for stuff merged in Sofia".
related: https://www.copperspice.com/
Moc is complex. reflection is complex. round one was trying to be as simple as possible while still allowing some real world use and allow room for the future.
Moc?
Meta-Object Compiler, a sort of preprocessor for code that uses Qt: https://doc.qt.io/qt-6/moc.html
"Reflection in C++26 might be insufficient for replacing moc."
C++ is such a dinosaur, that even after all these years the reflection that was lacking and was introduced is still unusable.
A dinosaur without which all the languages that build on top of GCC and LLVM would not exist.
C++ is like Bagger 288! The C stands for Coal.
https://www.youtube.com/watch?v=azEvfD4C6ow
1 reply →