Verdigris : Qt sans générateur de métaobjets

Le générateur de métaobjets de Qt, moc, est l’objet de recherches et de débats, ces derniers temps. L’année dernière, CopperSpice a été annoncé comme une bifurcation de Qt 4, l’objectif premier étant de se débarrasser du moc, en le remplaçant par des macros bien plus longues à écrire dans le code. Il y a peu, le mainteneur actuel du moc l’a défendu, en mettant en avant ses nombreux avantages par rapport à l’approche de CopperSpice, notamment pour l’écriture du code ou sa performance. Ce dernier revient à la charge : après avoir proposé une implémentation du moc basée sur des extensions du compilateur Clang ou la réflexion, il présente une autre approche qui exploite exclusivement les mécanismes de base des compilateurs C++ modernes.

Sous le nom de Verdigris se cache une implémentation du moc exclusivement à base de macros et d’expressions constantes de C++11 (entièrement compatible avec Qt 5). Il utilise une syntaxe très similaire à CopperSpice, mais, contrairement à ce dernier, génère toutes les données des métaobjets lors de la compilation (CopperSpice le fait à l’exécution du programme). Les avantages en performance sont multiples : lors de la compilation, un programme Verdigris prendra un peu moins de temps que son équivalent Qt direct… mais beaucoup moins que la version CopperSpice ! De plus, à l’exécution, tant Qt que Verdigris ont des surcoûts très faibles par rapport à CopperSpice, puisqu’ils ont généré l’entièreté des métaobjets à la compilation.


Ces différences d’implémentation ont également des impacts sur la compatibilité binaire, que tente de garantir Qt : l’approche suivie tant par Qt et Verdigris a cet objectif en tête (ce qui permet de changer la version des bibliothèques utilisées sans casser l’application), ce qui les empêche de réaliser certaines optimisations. Au contraire, CopperSpice cherche à optimiser certains appels de fonction et copie in extenso les données nécessaires à plusieurs endroits. Effectivement, CopperSpice est plus rapide pour certaines fonctionnalités, comme l’émission de signaux ; par contre, ces avantages sont contrebalancés par des fichiers exécutables bien plus gros et par un temps de chargement plus élevé.

Côté développeur, tant CopperSpice que Verdigris ont des syntaxes bien plus compliquées que celles permises par l’emploi d’un générateur de code : pour déclarer un dérivé de QObject, là où Qt se satisfait d’une macro Q_OBJECT, insérée dans la définition de la classe, CopperSpice impose une certaine redondance en donnant le nom de la classe en argument, Verdigris utilise même deux macros (l’une pour déclarer l’objet, l’autre pour générer le métaobjet correspondant).

Ces nouveaux développements montrent une fois de plus qu’il est possible de se passer du moc, mais en réalisant certains compromis, toujours défavorables en termes de syntaxe pour le moment. Ensuite, les détails d’implémentation montrent des résultats très différents en termes de compatibilité avec Qt (CopperSpice reste au niveau de fonctionnalités de Qt 4.8) et de performance.

Source : Verdigris: Qt without moc.
Voir aussi : les sources de Verdigris, le tutoriel.

Laisser un commentaire