C++ reflection (P2996) and moc

From Qt Wiki
Revision as of 21:37, 27 May 2025 by Peppe (talk | contribs)
Jump to navigation Jump to search

This is a WORK IN PROGRESS page to understand the implications of "Reflection for C++" for the future of Qt and moc.

Why?

moc extracts interesting metadata from QObject subclasses / gadgets / namespaces. This metadata is then used at runtime to implement many different QMetaObject facilities.

C++26 will (likely) ship with compile-time reflection. This means that the work that moc does today (as an external tool, with its custom lexer and parser etc.) could be done by the compiler itself. In the future, this may unlock lots of interesting possibilities (e.g. templated QObjects) and reduce technical debt (no need to maintain our own C++ parser for moc).

However, we're not sure how to get there just yet. Some questions that this work aims to answer:

  • Can we replace moc with a pure C++ solution?
    • Is there something missing from standard C++ that we need for moc?
  • How many source code (API) breaks are to be expected?
    • If there's breakage, can porting tools automate the transition?
  • Are there going to be issues with buildsystems?

Reflection for Standard C++: references

Papers that are interesting for Qt:

Triggers for moc

moc needs to be run on source files that define classes or namespaces and in which a "trigger keyword" is found: Q_OBJECT, Q_GADGET, Q_NAMESPACE, etc.

Usually, the buildsystem identifies these files, and prepares build rules so that moc is run on them.

The output of moc is some additional .cpp code (some static data, the implementation of various things declared by the Q_OBJECT macro, the implementation of the class' metaObject() function, the implementation of signals, ...)

This code can either get compiled standalone (and linked into the final target) via additional build rules, or directly included by a .cpp file (e.g. #include "moc_foo.cpp") in which case no additional rules are needed.

How to trigger reflection?

The main idea on the table is that we're going to need a macro.