Hacker News new | past | comments | ask | show | jobs | submit login
Moc myths debunked (woboq.com)
73 points by Tomte on June 22, 2016 | hide | past | favorite | 25 comments



Raymond Chen in his excellent The Old New Thing blog frequently asks - "What if two programs did this". What if every large C++ library came with their own custom preprocessor?

The major issue with moc is that it is evidence that Qt does not think of itself as just another C++ library that you can plug in to your code, but that it tries to be the programming environment and the fact that it uses C++ is just an implementation detail. Moc is only the most visible of the symptom of the underlying philosophy. It is also evidenced in the QCollections and by such things as QThread which duplicate much of the C++11 functionality.

When I evaluate a library for my project, I want it to think of itself as "just another C++ library", not "The Framework that you base everything in your application around".

Qt is a great illustration of Joe Armstrong's quote "You wanted a banana but what you got was a gorilla holding the banana and the entire jungle."


"...which duplicate much of the C++11 functionality."

In all fairness to Qt, the original version of the library predates the ISO approval of C++11 by 16 years! Much of the functionality the library provides was not even close to being available in the c++ standard libraries for many of the years since it was first released.

I understand if Qt is not your cup of tea, but many successful applications have been written with it, and a lot of that is due to the breadth of functionality the library provides (and in a cross-platform way). It's a tool like anything else, and I don't think it deserves to be dismissed out-of-hand.


I vaguely remember that Qt built their containers because at the time STL was young and not very well supported.


If I want to write a cross-platform GUI application supporting a single introspection, threading model and signals/slots mechanism for all members, then I'm asking for a jungle, not a banana. What parts of Qt would one want to split out and use separately? C++ stdlib collections not thread safe by default and cannot be used as drop-in replacements for Qt's collections. Qt's collections are designed specifically to work nicely inside its general framework, but would come at a speed cost used naively in some other sort of project. Also keep in mind that Qt is much older than C++11 and is just now switching to the standard library for its backend where possible. You can still use a non-c++11 compliant compiler with Qt 5.6 and utilize QThreads.

It reminds me of the argument that systemd is problematic because it's too big and complex. Well, sometimes it makes sense to write a complex system for the sake of ensuring that many complex components interoperate with ease, and system-wide changes can be coordinated between the libraries.


> What parts of Qt would one want to split out and use separately?

That's the wrong question. The right question is: what are you going to do, when you need to use 2-3-4-5 libraries and each one of them insist on using it's own primitives, collections, object hierarchies, etc. Are you going to spend your youth just writing shims to marshall data among them?


I don't know how much C++ you've done, but your "Ahah! BUT WHAT ABOUT" scenario sounds exactly like virtually every C++ project I've worked on. You have N libraries, and each library has its own string class and templated array class, all with different member function names.

The answer to your question is: yes. Usually you're going to do some transformation or processing when moving from one type to the other, so you just fold the conversion into that. It's stupid and you roll your eyes and you just kind of carry on.


> scenario sounds exactly like virtually every C++ project I've worked on

That's exactly the point :). It is not only C++, but also C problem. Maybe I've grown coddled with Java, Python and a few other languages, where the third party libraries do agree on the types they use.


Is that a problem that anyone shipping products built with Qt is actually running into, though?

Yeah, it's a GUI App Framework, not a GUI library. Yeah, it would be hard for 2-3-4-5 App Frameworks to co-exist. But how often would that ever come up? Frameworks, unlike libraries, aren't intended to be mix-and-match. Complaining about that is like complaining that water is wet.


> C++ stdlib collections not thread safe by default and cannot be used as drop-in replacements for Qt's collections.

I agree with other parts of your post, but not this. How is Qt's collections thread safe in any way? And won't that be a huge performance cost, since most of the time, collections do not need to be thread safe?


They are not (generally) thread safe. Quoting http://doc.qt.io/qt-4.8/threads-reentrancy.html

> Many Qt classes are reentrant, but they are not made thread-safe, because making them thread-safe would incur the extra overhead of repeatedly locking and unlocking a QMutex. ...

> Some Qt classes and functions are thread-safe. These are mainly the thread-related classes (e.g. QMutex) and fundamental functions (e.g. QCoreApplication::postEvent()).


Qt is a framework, not a library. Frameworks usually expect apps to conform to their particular way of doing things.

If one wants to use Qt as a library, I think one can ignore the moc now that lambdas can be used as slots in a signal-slot relationship. Now that the standard C++ lib is high quality on most platforms, one could also ignore the threads/containers.


I never understood the problem with moc. It's an extra step during the build process, yes. But it's quick and very easy to integrate in modern build tools (for example CMake).


From what I can understand, all the arguments seem to derive from some grumpy old curmudgeon who took a passing glance at Qt 15 years ago, without actually understanding what it is or does, and said "Why do I need this thing? I don't like extra stuff because 'reasons'. Its better if I reinvent the wheel myself. Preprocessors are always bad. Now get off my lawn!"

Moc was introduced at a time that C++ really did not have the built-in features necessary to create a framework like Qt. Since then, a few things have happened. First, C++ itself has (very) slowly gained some of those features. Second, the Qt developers have found additional things they can do by having the "moc" tool integrated into their build processes, and thus have expanded its scope.

But even if a day comes that Qt can totally get rid of "moc" in theory, in actuality there will still be a lot of people who actually need to use C++ compilers that still haven't implemented whatever new version of the standard accomplishes this.


Me neither, specially because most C and C++ developers seem to be quite happy to use compiler specific extensions to ANSI C and ANSI C++.

So using moc isn't ok as it ties the application to an extra tool, but using features that tie the application to a specific compiler is ok.


It's been 14 years since I last used a precompiler like moc (it wasn't moc), and it was a pain - all the nice IDE features (syntax highlighting, code completion, automatic indentation, source level debugging, etc.) were all broken in subtle or major ways.

moc (specifically) has a long track record that I would expect this to be solved -- no experience myself -- but regardless of how easy it is to add another build step, most precompilation stages are correlated with reduced tool functionality.


moc isn't a precompiler - it will not change your code in any way! It merely generates additional code based on your classes containing meta information


There was some movement to rewrite QT things in templates or whatever (so that it's stock C++) but I lost track of it and kinda abandoned C++ altogether.

Have there been progress with this?


CopperSpice - it's discussed in the article



This doesn't need to be debated ad infinitum. Is there a single page that can be pointed to as the authority on what moc is, what it provides, why it works the way it does, why it's good and why it's bad - and we leave it at that? It's been around long enough.


What advantages does moc provide compared to C++14/17 facilities?


While I'm not 100% on Qt's history, some quick Googling finds references that suggest moc was around in the Qt2 days, which was 1999, which was before even C++03 was a thing. So it's mostly a historical relic, now hidden away as much as possible by things like automoc in cmake.

Also, FWIW, moc-ng is based on libclang, which looks to be vaguely in the general direction of what you're getting at: https://woboq.com/blog/moc-with-clang.html


it does provide some limited reflection which is in my opinion the biggest missing feature in C++. (and no, I dont want to use macros for this)


I think this article would be better if it mentioned some more criticisms that are actually valid. This way it reads very one-sided, especially for people like me who are not familiar with QT.


> criticisms that are actually valid

Such as? I have developed Qt applications for many years and never noticed downsides of the moc approach.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: