Pourquoi quake 3 a été programmé en C et non en C++

Déjà, je ne suis pas sûr si la question est posée au bon endroit, dites le moi je bougerais le post ailleurs (si le forum le permet).

Mon expérience en programmation est sûrement plutôt réduite que grande, néanmoins je trouve la programmation objet assez “bourrin” (pour reprendre une expression d’un ancien camarade de classe), et je ne sais pas exactement si le C++ facilite la programmation grace au classes (la programmation n’a pas a mon sens à être facile, meme si pour certains projets gargantuesques, l’encapsulation s’avère nécessaire, namespaces ou pas), tout en conservant une rapidité d’exécution équivalente (je parle de jeux vidéos, qui sont quand meme des programmes sensibles a l’optimisation).

Voilà ma question :
Pourquoi Quake 3 a t’il été développé en C, et pas en C++ ? Y avait il une préférence à l’époque pour le C, ou bien est-ce la raison pour laquelle ce moteur est si rapide, ou bien est ce parce que quake 3 reprend une base de Quake 2, qui lui-même… bref. Ou bien encore est ce parce qu’a l’époque (1998) c’est l’apparition des pixel/vertex shaders (je ne suis pas sur, corrigez moi) et parce que ca induisait certains choix technologiques auxquels on entendra plus jamais reparler grâce à l’évolution des cartes graphiques, ou je ne sais quoi encore.

Bon, pour ce qui est de la réponse à ta question, je n’ai qu’un modeste avis, à défaut de connaître la vraie raison. Pour ma part, je pense que ce n’est que (très) partiellement pour une questions de perfs, et que la vraie raison tient à une équipe et à un choix technologique, tout bêtement. Si les gards d’ID maîtrisaient le C et savaient coder en C (doux euphémisme), peut-être qu’ils n’avaient tout simplement pas besoin de ce que le C++ peut apporter (classes, templates, STL).

Question performance, le C++ n’est de toute manière pas en reste, tout dépend comme toujours du but dans lequel on l’utilise. Si on se contente d’utiliser les ctors et dtors pour éviter de devoir gérer la création et la destruction des objets à la mano, si on n’a ni besoin de late binding, ni de RTTI, ni d’exceptions, si on inline (intelligemment, s’entend), alors C et C++ ne doivent pas être si éloignés (même si j’avouerai honteusement ne m’être jamais amusé à comparer les deux). Si on ajoute les template, et donc la métaprogrammation, sans oublier les containers et algos de la STL qui évitent de réinventer la roue (souvent en moins bien), on peut même générer du code de manière efficace, évalué à la compilation plutôt qu’au runtime, et j’en passe. Et puis de toute manière, si l’on se tient à la sempiternelle règle des 80/20, il vaut mieux sortir son profiler pour trouver les bouts de code qui sont réellement un problème.

Quant au côté bourrin de la programmation objet, ça dépend comme toujours de la qualité des programmeurs derrière le code. J’ai déjà vu du code C++ qui n’en avait que le nom (zéro encapsulation, tout en public, “au mieux” en protected, ha ha). Au contraire on peut pondre du code C++ dont les interfaces sont clean et font ce qu’elles promettent, sont faciles à comprendre et utiliser sans erreurs. Le pire ennemi du C++, c’est peut-être le C++ lui-même et l’explosion combinatoire des designs qu’il permet. Bourriner en C++, ne pas se poser la question des interfaces, de ce que l’on souhaite permettre au client de réaliser, des garanties que l’on souhaite lui offrir, du niveau d’isolation que l’on souhaite assurer, etc…, c’est demander des problèmes. Tôt ou tard on le paie soit avec des interfaces moisies qui révèlent ce qu’elles ne devraient pas, des designs monolitiques, des structures physiques qui deviennent ingérables ou des temps de compilation qui prennent l’ascenseur. Bourriner en C++, ça peut se faire lorsqu’on programme sur un coin de nappe, mais dès qu’on voit un peu plus grand, ça peut vite conduire à une impasse.

Au contraire on peut pondre du code C très objet dans l’esprit, avec de l’encapsulation, évitant le code spaghetti, avec des interfaces soignées et des dépendances bien étudiées. Ca ne dépend pas du projet, ça ne dépend pas de la techno, là encore ça dépend des gens et de la volonté de certains à penser “interface-oriented”, même dans un langage procédural comme le C. Alors oui, certaines technos sont plus faciles que d’autres, certaines encouragent certaines formes de design, certaines sont plus permissives, certaines bien plus productives que le C et le C++, mais derrière tout ça, c’est toujours une histoire d’équipe, de talent, de passion, de partage et de curiosité.

Quant aux raisons pour lesquelles le code de Q3 est rapide, là aussi je pense que c’est une histoire de codeurs brillantissimes plutôt que de techno. L’algo de calcul rapide de 1/sqrt(x) aurait très bien pu s’implémenter en C++, il n’en aurait pas été moins efficace.

Oui, si tu jettes un oeil au code de Q3 (libre, je le rapelle), tu verras que c’est effectivement du C, mais avec quand meme de grands concepts objet dedans. Je ferais un post plus detaillé plus tard, ya des choses a dire :smiley:

Je ne m’aventurerai pas en terrain inconnu avec la comparaison C/C++.

En revanche et ca ne fait que déplacer le pb de quelques années, le moteur de Quake3 est basé sur l’IDTech2, lui même basé sur le QuakeEngine qui est sorti en 96 et était codé en C/ASM. On a clairement affaire à un bon gros LegacyProject où on a donc construit sur le code existant plutôt que de réinventer la roue. Quand au choix du C plutôt que le C++ en 94 ou 95 (?!) un élément de réponse se situe peut-être dans l’accélération hardware inexistante?

Je me souviens à l’époque avoir téléchargé la partie libre du code source (peut-être entièrement libre maintenant ?) et j’avais bien apprécié la clarté du code. Un bel exemple de code propre et bien structuré :smiley: Peu de majuscules par exemple si mes souvenirs sont bons. C’est un détail mais ç’est plus agréable visuellement.

A propos saviez-vous que John Carmack va être récompensé prochainement à la GDC pour sa contribution au jeu vidéo ? Un article intéressant à ce sujet ici. Ca fait plaisir car c’est une personnalité assez discrète et qui travaille beaucoup. (Si j’avais son cerveau… :D)

Juste une petite remarque pour dire que le concept objet ne dépend pas du tout du langage. Il est tout a fait possible d’appliquer les concepts objet en langage C, pas mal de bibliothèques UNIX basées sur la GLib sont pensées objet comme GTK, GStreamer, … Il y a même un language objet VALA qui reprend la syntaxe et pas mal d’idée de Java/C# et qui transforme ensuite le code en bon vieux C oldschool pour la compilation.

La programmation est un art qui demande des années de pratique pour être bien maitrisée quelque soit le langage.

Sur Yahoo Answers:

En gros, programmer en C++ permet de générer du code C optimisé a ce qu’on vraiment faire, j’étais vraiment pas au courant de ca :|, je pensais que le C++ était vraiment indépendant du C dans la génération de l’exécutable…
Merci pour toutes les mots savant Doc toise, ca me fait chercher et j’apprend plein de choses :smiley:

J’allais ajoute que c’est aussi par ce que le c++ c’est un language de gonzesses, mais je trouve cette citation de meilleur esprit:

« C makes it easy to shoot yourself in the foot; C++ lets you reuse the bullet »

:smiley:

Le C++ precompilé en C ? C’est louche quand meme.

J’ai un doute aussi la …

[quote=“jokoon, post:7, topic: 50838”]Sur Yahoo Answers:

En gros, programmer en C++ permet de générer du code C optimisé a ce qu’on vraiment faire, j’étais vraiment pas au courant de ca :|, je pensais que le C++ était vraiment indépendant du C dans la génération de l’exécutable…
Merci pour toutes les mots savant Doc toise, ca me fait chercher et j’apprend plein de choses :D[/quote]
C’est completement faux. Pas que ca soit impossible theoriquement de compiler du C++ en C (notion de machine turing complete et equivalente/theorie des languages), apres tout tous language compile en language machine qui est lui meme “interprete” en microcode, mais c’est absoluement pas comme ca que ca marche dans l’ecrasante majoritee des compilateurs modernes.

En fait je faisais allusion à l’évaluation de code à la compilation en émulant des loops via des templates récursifs. L’exemple type, c’est le calcul des factorielles à la compilation pour avoir directement le résultat “inliné” dans le code généré, alors que l’approche C aurait été une fonction récursive. Pour autant que le n dont on calcule la factorielle soit connu à la compilation, le résultat n’a donc pas besoin d’être calculé au runtime.

Euuhh si : La programmation a à être facile (mais non limitante).

Pour faire un parallèle pour construire une maison de nos jours on ne taille pas les pierres une par une.

En programmation c’est pareil. Des tas de problèmes difficiles ont été résolus depuis longtemps et encapsulés. Ils nous permettent d’accéder à un niveau supérieur de difficulté, de nous concentrer sur ce qui est vraiment nouveau.

J’ai pas mal fait de C orienté perf dans ma carrière. Et pourtant ce que je fais en ce moment (orienté perf/multithreading) je n’imagine même pas le faire en C. Ca serait pas les mêmes coûts de dev.

Bon, faut dire que la puissance des machines et la taille mémoire aide aussi, c’est plus confortable qu’il y a dix ans.

Il y a aussi l’EIFFEL dont le compilo produit du C. C’était ma séquence nostalgie.

[quote=« c0unt0, post:8, topic: 50838 »]J’allais ajoute que c’est aussi par ce que le c++ c’est un language de gonzesses, mais je trouve cette citation de meilleur esprit:

« C makes it easy to shoot yourself in the foot; C++ lets you reuse the bullet »

:)[/quote]
Ah j’aime beaucoup :smiley:

Sinon, j’aurais tendance a dire qu’actuellement, y a plus vraiment de difference entre le C et le C++ en terme de perfs, les machines actuelles ayant lisse un peu la courbe d’optimisation (c’est comme pour l’asm ou les compilos sont devenus meilleurs que les humains en general). En revanche, il y a 10 ans, il y avait peut etre encore cette difference.

Ou tout simplement les gars d’ID etaient plus experimente en C qu’en C++ hein.

LoneWolf
Et le C# dans tout ca? Bah j’apprends lentement :smiley:

Il me semble me rappeler avoir lu un article à l’époque de la sortie de Doom 3 (premier jeu ID Software developpé en C++) qui expliquait que si ID Software était resté si longtemps sur C c’était simplement une question de préférence personnelle, particulièrement de la part de Carmack.

Ils expliquaient qu’ils avaient tellement investi dans le C et atteind un tel niveau de maîtrise de leurs outils qu’il était très difficile de partir sur quelque chose de totalement différent et “tout” réapprendre.

Je me souviens aussi que l’article indiquait les raisons du passage à C++ pour Doom3, mais je ne m’en souviens plus très bien et je n’arrive pas à remettre la main sur cet article.

Si vous voulez tout savoir Halo/Halo 2 c’etait aussi du C =) pour les meme raisons.

heu, je crois que tu melanges tout … l’approche recursive ou iterative n’a rien a voir avec le choix du langage, meme si certain langage sont plus a l’aise dans un mode ou l’autre (lisp par ex est pensé pour faire du recursif).

Apres le recursif, c’est de la gestion de pile, donc ca fini toujours en iteratif une fois compilé. Mais ca a juste rien a voir avec ton histoire de C / C++ …
A l’ecole, le hello world du recursif, c’est le calcul du factoriel. Et je l’ai écrit en C, en C++, en lisp, en java, …

Anecdote: en vidant le grenier, un jour, avec mon père, il me ressort le calcul recursif du factoriel qu’il avait codé en école d’ingé… sur ruban a trous. :smiley:

[quote=“cben76, post:17, topic: 50838”]heu, je crois que tu melanges tout … l’approche recursive ou iterative n’a rien a voir avec le choix du langage, meme si certain langage sont plus a l’aise dans un mode ou l’autre (lisp par ex est pensé pour faire du recursif).

Apres le recursif, c’est de la gestion de pile, donc ca fini toujours en iteratif une fois compilé. Mais ca a juste rien a voir avec ton histoire de C / C++ …[/quote]
Je parlais pas du fait que le récursif ou l’itératif dépend du langage, ce que je voulais dire, c’est qu’en C++ ça dépend de l’aspect du langage qu’on utilise. Si on programme dans la partie C du C++, on peut coder la factorielle aussi bien sous forme d’une boucle que d’une fonction récursive. Mais si on veut coder une boucle en métaprogrammation, on est obligé de le faire en codant un template qui s’utilise lui-même, avec une spécialisation pour terminer la récursion.

Ce que le monsieur veux dire, c’est que grace a la “puissance” des templates, le C++ va generer la factorielle a la compilation, et non pas a l’execution du code.

Maintenant, entre les trucs decrits dans cet article et les utilisation dans la vie courrante, il y a une grosse difference: Les templates utilises pour du vrais code sont souvent plus simple (et moins long a compiler…)