Kevin Kofler
: Euh, lequel?
345 ?
nitro
:Kevin Kofler
: Je ne suis pas d'accord! Les standards ISO ne sont pas là pour que M$ fasse ce qu'ils veulent!
Pourtant les développeurs de GCC ne se sont pas gené pour rajouter leurs extensions au standard C...
Certes, mais eux ils s'en fichent toujours du caractère non-standard des MFC, ils le font même exprès pour empêcher à leurs concurrents de les utiliser avec leurs compilateurs.
Bien sûr tu as des preuves concretes pour accuser de la sorte.
C'est quoi l'interet d'un OS comme MenuetOS sur lequel on ne peut utiliser aucun logiciel existant ?
Sur BeOS non plus...![]()
AtheOS est quand-même à peu près compatible avec POSIX, mais BeOS carrément pas.
Pourtant sur les 3000 fichiers de BeBits.com, une grande partie sont des portages de logiciels existant sur d'autres plateformes... me demande bien comment ils font![]()
Reviens quand tu auras mis BeOS sur une disquette et quand elle sera toujours à moitié vide.
Chose vachement utile de nos jours...
Même les consoles et téléphones portables, et les PDA sont suffisamment équippés pour faire du Java et du C++ (cf. SymbianOS). On pourrait penser que pour faire des perfs sur ces plateformes on est obligé de passer par de l'assembleur. Eh bien même pas... les gourous de flipcode eux-mêmes font leur moteur 3D en C++ pour les telephones portables.
Et puis écrire un assembleur ça fait beaucoup plus de lignes de code, et c'est un enfer à maintenir, sans parler du fait que ça ne tourne que sur une seule plateforme.
C'est pour ça que le C (pas le C++) existe.
Ok alors maintenant transpose un niveau plus haut. C'est parce que les gros logiciels en C sont impossibles à maintenir que le C++ existe.
1ere constatation : gcc produit exactement le même code pour les deux.
Pas toujours. Regarde un peu dans Bugzilla, il y a pas mal de problèmes avec les templates.
- dans ce cas, ça produit exactement le même code (j'ai testé) ;
- ce n'est pas parce qu'une implémentation de compilateur est buggée que le langage est mauvais.
2eme constatation : la version template est plus lisible (donc plus facile à maintenir), car c'est une fonction C++ normale, pas besoin d'extension GNU, de variables avec des underscores (qui vont collisionner en plus si on appelle min(_a, x)), et pas de parenthèses superflues autour des paramètres.C'est subjectif. Pour moi, la macro est au moins aussi claire que le template. Et même pour le compilateur, les macros sont plus "lisibles" (faciles à parser), les templates causent plein de conflits de parsing.
Subjectif ? Clairement j'ai cité les raisons pour lesquelles la macro est moins lisible. De plus la collision elle, n'est pas subjective. Et enfin, côté compilateur ça marche suffisamment bien pour être utilisé dans tout plein de projets, dont la STL.
3eme constatation : la version template bénéficie d'un des avantages du typage, à savoir un message d'erreur clair en cas d'erreur de typage.Message d'erreur chinois typique du C++.
- version template : "error: no matching function for call to `min(st&, int)'" où il y a clairement la fonction et les types impliqués ;
Tu le fais franchement exprès... ou alors on n'a pas la même définition de chinois. Traduit tout bêtement en français ça dit "aucune fonction correspondant à l'appel de la fonction min avec deux arguments de type st& et int". C'est une description exacte et précise du problème.
- version macro : "error: invalid operands to binary <" alors que sur la ligne concernée il n'y a même pas de '<'.Très clair comme erreur. Comparaisons entre 2 types incompatibles, donc opérandes invalides pour un opérateur de comparaison. Là, je sais tout de suite ce qui ne va pas.
Sauf qu'il n'y a pas d'opérateur de comparaison "<" sur la ligne. L'erreur décrit ce qu'il y a après expansion de la macro. L'utilisateur lui, utilise la syntaxe d'un appel de fonction, donc il s'attend à retrouver la sémantique de l'appel de fonction, et ce n'est absolument pas le cas. Bien souvent il ne connait même pas le contenu de la macro.
Pire encore, imagine qu'on ai : return min(a, 5) < 4; Pour peu que les éléments soient un peu plus compliqués, voir cachés dans d'autres macros, le message d'erreur parle d'un opérateur '<', et il y en a effectivement un sur la ligne. Mais pas de chance c'est pas de celui-là dont on parle.
Donc non, tu ne me fera pas croire que ce message d'erreur est mieux que le précédent. Désolé.
4eme constatation : la version template bénéficie d'un avantage que la version macro ne peut pas faire, c'est la spécialisation en fonction du type de données. Effectivement, si dans mon programme j'utilise des types de données particuliers dont la fonction min peut être codée de manière beaucoup plus efficace (par exemple les entiers de l'intervale [0,1])
Euh, il n'y en a pas beaucoup là.
J'ai pris un exemple simple pour que tout le monde voit bien de quelle optimisation je parle![]()
#define min(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); (__builtin_types_compatible_p(typeof(_a),mastruct) && __builtin_types_compatible_p(typeof(_b),mastruct))? (_a.value && _b.value) : (_a < _b ? _a : _b;) })
Tu trouves ça lisible par rapport à ma spécialisation ? En plus là les deux doivent être définis au même endroit. Ce n'est pas le cas dans mon exemple.
Je posterai un exemple de ld-tigcc quand je serai de retour chez moi. Non seulement, les macros sont utilisées comme des templates et ça marche très bien, mais on fait aussi du Item ## s pour construire un pluriel. Bonne chance pour faire ça avec un template.
Construire le pluriel d'un identifiant c'est ce qu'on appelle du bidouillage![]()
Et le nombre de choses qu'on peut faire avec des templates est bien supérieur à ce qu'on peut faire avec les macros, car le meta-langage des templates est turing complete. cf C++ Templates and Turing Completeness.
Certains peepholes sont mieux exécutés tout à la fin, donc en define_peephole.Tu ne va pas me faire croire qu'il vaut mieux executer un peephole une seule fois plutôt que plusieurs fois itérativement jusqu'à ce que le code converge...
nitro
:Kevin KoflerBien sûr tu as des preuves concretes pour accuser de la sorte.
:Certes, mais eux ils s'en fichent toujours du caractère non-standard des MFC, ils le font même exprès pour empêcher à leurs concurrents de les utiliser avec leurs compilateurs.
Pourtant sur les 3000 fichiers de BeBits.com, une grande partie sont des portages de logiciels existant sur d'autres plateformes... me demande bien comment ils fontC'est quoi l'interet d'un OS comme MenuetOS sur lequel on ne peut utiliser aucun logiciel existant ?
Sur BeOS non plus...
AtheOS est quand-même à peu près compatible avec POSIX, mais BeOS carrément pas.
Reviens quand tu auras mis BeOS sur une disquette et quand elle sera toujours à moitié vide.Chose vachement utile de nos jours...
Même les consoles et téléphones portables, et les PDA sont suffisamment équippés pour faire du Java et du C++ (cf. SymbianOS). On pourrait penser que pour faire des perfs sur ces plateformes on est obligé de passer par de l'assembleur. Eh bien même pas... les gourous de flipcode eux-mêmes font leur moteur 3D en C++ pour les telephones portables.
Ok alors maintenant transpose un niveau plus haut. C'est parce que les gros logiciels en C sont impossibles à maintenir que le C++ existe.Et puis écrire un assembleur ça fait beaucoup plus de lignes de code, et c'est un enfer à maintenir, sans parler du fait que ça ne tourne que sur une seule plateforme.
C'est pour ça que le C (pas le C++) existe.
- ce n'est pas parce qu'une implémentation de compilateur est buggée que le langage est mauvais.
Subjectif ? Clairement j'ai cité les raisons pour lesquelles la macro est moins lisible.2eme constatation : la version template est plus lisible (donc plus facile à maintenir), car c'est une fonction C++ normale, pas besoin d'extension GNU, de variables avec des underscores (qui vont collisionner en plus si on appelle min(_a, x)), et pas de parenthèses superflues autour des paramètres.C'est subjectif. Pour moi, la macro est au moins aussi claire que le template. Et même pour le compilateur, les macros sont plus "lisibles" (faciles à parser), les templates causent plein de conflits de parsing.
De plus la collision elle, n'est pas subjective.
Et enfin, côté compilateur ça marche suffisamment bien pour être utilisé dans tout plein de projets, dont la STL.
Tu le fais franchement exprès... ou alors on n'a pas la même définition de chinois. Traduit tout bêtement en français ça dit "aucune fonction correspondant à l'appel de la fonction min avec deux arguments de type st& et int". C'est une description exacte et précise du problème.3eme constatation : la version template bénéficie d'un des avantages du typage, à savoir un message d'erreur clair en cas d'erreur de typage.Message d'erreur chinois typique du C++.
- version template : "error: no matching function for call to `min(st&, int)'" où il y a clairement la fonction et les types impliqués ;
Sauf qu'il n'y a pas d'opérateur de comparaison "<" sur la ligne. L'erreur décrit ce qu'il y a après expansion de la macro. L'utilisateur lui, utilise la syntaxe d'un appel de fonction, donc il s'attend à retrouver la sémantique de l'appel de fonction, et ce n'est absolument pas le cas. Bien souvent il ne connait même pas le contenu de la macro.
Pire encore, imagine qu'on ai : return min(a, 5) < 4; Pour peu que les éléments soient un peu plus compliqués, voir cachés dans d'autres macros, le message d'erreur parle d'un opérateur '<', et il y en a effectivement un sur la ligne. Mais pas de chance c'est pas de celui-là dont on parle.
#define min(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); (__builtin_types_compatible_p(typeof(_a),mastruct) && __builtin_types_compatible_p(typeof(_b),mastruct))? (_a.value && _b.value) : (_a < _b ? _a : _b;) })Tu trouves ça lisible par rapport à ma spécialisation ?
En plus là les deux doivent être définis au même endroit. Ce n'est pas le cas dans mon exemple.
Je posterai un exemple de ld-tigcc quand je serai de retour chez moi. Non seulement, les macros sont utilisées comme des templates et ça marche très bien, mais on fait aussi du Item ## s pour construire un pluriel. Bonne chance pour faire ça avec un template.
Construire le pluriel d'un identifiant c'est ce qu'on appelle du bidouillage
Et le nombre de choses qu'on peut faire avec des templates est bien supérieur à ce qu'on peut faire avec les macros, car le meta-langage des templates est turing complete. cf C++ Templates and Turing Completeness.
Certains peepholes sont mieux exécutés tout à la fin, donc en define_peephole.Tu ne va pas me faire croire qu'il vaut mieux executer un peephole une seule fois plutôt que plusieurs fois itérativement jusqu'à ce que le code converge...
Pas nécessairement: * librairie système: #define _min(__a,__b) ({ typeof (__a) _a = (__a); typeof (__b) _b = (__b); (_a < _b ? _a : _b;) }) #define min _min * librairie supplémentaire: #define libtoto_min(a___,b___) ({ typeof (a__) a_ = (a__); typeof (b__) b_ = (b__); (__builtin_types_compatible_p(typeof(a_),mastruct) && __builtin_types_compatible_p(typeof(b_),mastruct))? (a_.value && b_.value) : (_min(a_,b_)) }) #undef min #define min libtoto_min Et le programme utilisateur peut encore étendre min en s'appuyant sur libtoto_min.
Kevin Kofler
:Va voir leurs EULAs récents pour MFC et compagnie si tu veux savoir ce qu'ils pensent des compilateurs concurrents.
Bon, je viens de vérifier et en effet il y a une librairie de compatibilité POSIX livrée avec BeOS.Mais l'existence ou non d'une librairie de compatibilité POSIX n'a pas grand chose à voir avec le langage de programmation utilisé pour coder le système d'exploitation.
Ben oui, c'est utile si un OS prend moins de place! Les disques durs ne sont pas gratuits!
les gourous de flipcode eux-mêmes font leur moteur 3D en C++ pour les telephones portables.
Bonjour la lenteur...
Impossibles à maintenir? Linux, GCC etc., tout ça c'est impossible à maintenir??? Je vois le contraire, moi...
Un langage difficilement réalisable en un compilateur est un langage excessivement complexe, donc mal conçu.
Subjectif ? Clairement j'ai cité les raisons pour lesquelles la macro est moins lisible.Ben, tes raisons ne me convainquent pas:
Tu trouves ça lisible par rapport à ma spécialisation ?Euh... Pas spécialement.
De plus la collision elle, n'est pas subjective.Elle n'existe pas. L'utilisation de noms de variables commençant par un underscore est interdite aux programmes utilisateur, en C comme en C++.
#define _min(__a,__b) ... #define libtoto_min(a__,b__) ...
Ce n'est pas exact et précis. Le problème est que les types à gauche et à droite ne sont pas comparables, le message d'erreur n'en dit rien. "error: invalid operands to binary <" dit clairement qu'il y a des opérandes incomparables.
Les développeurs de GCC comptent donner les colonnes des erreurs, ce qui résoudra ce problème.
Construire le pluriel d'un identifiant c'est ce qu'on appelle du bidouillage
Comment veux-tu faire autrement? (cf. ./383)
D'un côté oui. De l'autre côté, les macros permettent de travailler sur les tokens (par exemple Item ## s), les templates ne le permettent pas. Donc chacun permet quelque chose que l'autre ne permet pas.
Lis les archives de la mailing list de GCC plus attentivement.
nitro :C'est d'ailleurs assez impressionnant.
Et en ce qui concerne la place, Symbian OS sur téléphones portables est en C++, avec toutes les apps en C++/Java et ça tourne plutôt bien
[...] Les jeux tournent très bien, et sont bien rapides.
nitro
:De plus Visual C++ 7 est tout aussi standard que G++.
Ben oui, c'est utile si un OS prend moins de place! Les disques durs ne sont pas gratuits!Entre un OS sur une disquette qui supporte 0 application, et un OS sur CD qui supporte des milliers d'applications, le choix est vite fait.
Et en ce qui concerne la place, Symbian OS sur téléphones portables est en C++, avec toutes les apps en C++/Java et ça tourne plutôt bien.
Impossibles à maintenir? Linux, GCC etc., tout ça c'est impossible à maintenir??? Je vois le contraire, moi...On a deja dit que justement GCC est le pire exemple.
Et Linux n'est pas très gros, la plus grande partie du code source ce sont les drivers.
Subjectif ? Clairement j'ai cité les raisons pour lesquelles la macro est moins lisible.Ben, tes raisons ne me convainquent pas:
Ah, pourtant un peu plus loin, tu me réponds :Tu trouves ça lisible par rapport à ma spécialisation ?Alors il faudrait savoir.Euh... Pas spécialement.
Ah bon, pourtant tu en as mis dans tes macros.De plus la collision elle, n'est pas subjective.Elle n'existe pas. L'utilisation de noms de variables commençant par un underscore est interdite aux programmes utilisateur, en C comme en C++.
Et pourquoi est-ce que dans ton exemple de spécialisation tu as :#define _min(__a,__b) ... #define libtoto_min(a__,b__) ...Pourquoi pas __a et __b partout ?
Ce n'est pas exact et précis. Le problème est que les types à gauche et à droite ne sont pas comparables, le message d'erreur n'en dit rien. "error: invalid operands to binary <" dit clairement qu'il y a des opérandes incomparables.Arrête de faire semblant de ne pas comprendre. Min passe encore, mais dans le cas d'une macro plus compliquée à laquelle le programmeur n'a pas accès, le message d'erreur ne veut absolument rien dire puisqu'il indique une ligne sur laquelle il y a du code différent de ce qu'a vu le compilateur.
Les développeurs de GCC comptent donner les colonnes des erreurs, ce qui résoudra ce problème.Ca ne résoud rien du tout, car il suffit d'une seule macro sur une ligne pour invalider tous les numeros des colonnes suivantes.
Très franchement je n'ai pas cherché à comprendre ton code car je le trouve complètement illisible.Construire le pluriel d'un identifiant c'est ce qu'on appelle du bidouillage
Comment veux-tu faire autrement? (cf. ./383)
Lis les archives de la mailing list de GCC plus attentivement.Et moi je te conseille un article de Zachary Weinberg, de CodeSourcery, qui s'intitule "A Maintenance Programmer's View of GCC", paru lors du GCC Summit 2003, dans lequel il expose les problèmes de maintenance dont souffre GCC. Ce n'est pas beau à voir.
Kevin Kofler
:De plus Visual C++ 7 est tout aussi standard que G++.Sûr?
Q: Microsoft people have been hinting about the conformance work in this release for well over a year. What exactly are we getting?
A: In Everett [codename for the next release of Visual Studio .NET] we've achieved 98% conformance to the C++ ISO standard. No compiler reaches 100%, and it turns out that conformance is a difficult thing to measure since there is no singly accepted test suite. We used 3 - Perennial, Plumb Hall, and Dinkumware - and are passing each above the 98% line. But our favorite benchmark is that we're compiling the popular Boost, Blitz, and Loki libraries without the need for special workarounds. We feel that the great number of innovations in C++ are occurring in these community written libraries, and it is important that Visual C++ be able to compile them. Visual C++ developers will now be able to use the same libraries that the rest of the C++ community, making them part of the greater C++ community. That aside, we'll finally be able to write code using some of the advanced template features defined in the standard.
Et ils ont combien de mémoire, ces téléphones portables?
Je ne trouve pas si lourd que ça de travailler dessus. Oui, le code est illisible par morceaux, mais je pense que ça serait bien pire s'il y avait ces !"§$%&/()=? de templates dans tous les sens.
Pour les spécialisations avec du code différent, les macros s'en tirent moins bien. Mais pour quelque chose de vraiment générique (ce qui est ce pour quoi les templates sont faits normalement!), les macros marchent très bien.
Elle n'existe pas. L'utilisation de noms de variables commençant par un underscore est interdite aux programmes utilisateur, en C comme en C++.Ah bon, pourtant tu en as mis dans tes macros.
Parce que ma macro min appartient à la librairie système qui a le droit d'utiliser ces identifiants.
Arrête de faire semblant de ne pas comprendre. Min passe encore, mais dans le cas d'une macro plus compliquée à laquelle le programmeur n'a pas accès, le message d'erreur ne veut absolument rien dire puisqu'il indique une ligne sur laquelle il y a du code différent de ce qu'a vu le compilateur.
Solution: gcc -E.
Et le programmeur a forcément accès à la macro au moins en lecture parce que sinon, la macro ne fonctionne pas.
Les développeurs de GCC comptent donner les colonnes des erreurs, ce qui résoudra ce problème.Ca ne résoud rien du tout, car il suffit d'une seule macro sur une ligne pour invalider tous les numeros des colonnes suivantes.
Si c'est bien fait (vu que ce n'est pas encore fait, je ne peux pas le dire à coup sûr), il donnera la colonne avant expansion des macros. Si l'erreur est dans la macro, il indiquera probablement le nom de la macro.
Moi, je lis vraiment ce qu'on me demande de lire.
J'étais déjà au courant de pas mal des critiques exposées dans cet article. Il faut savoir:
\[snip\]
Voila, très bien. Le C++ dispose des deux, le C n'en a qu'un seul. L'avantage est donc au C++.
nitro
:Je n'ai pas le droit d'avoir une macro my_min dans un code source utilisateur ?Elle n'existe pas. L'utilisation de noms de variables commençant par un underscore est interdite aux programmes utilisateur, en C comme en C++.Ah bon, pourtant tu en as mis dans tes macros.
Parce que ma macro min appartient à la librairie système qui a le droit d'utiliser ces identifiants.
Ok alors en C++ avec des templates on a un message d'erreur qui indique précisement où est l'erreur. Et si on utilise des macro on peut être contraint de se taper la sortie du préprocesseur, voire même la lecture des headers systèmes pour savoir ce qui cloche. Ca ne me semble pas très pratique.
Moi, je lis vraiment ce qu'on me demande de lire.
Qu'est-ce que tu insinues ?Je pense que je lis plus de messages que toi étant donné que dans le labo où je travaille (dont une des spécialités est la compilation), il y a un mirroir de la mailing list GCC en newsgroup local.
J'étais déjà au courant de pas mal des critiques exposées dans cet article. Il faut savoir:
\[snip\]
Ca ne change rien aux problèmes de maintenance de GCC
Et pour finir je retiendrais que tu n'a pas répondu à ceci :
Voila, très bien. Le C++ dispose des deux, le C n'en a qu'un seul. L'avantage est donc au C++.
donc j'en déduis que tu es d'accord.. nah
Kevin Kofler
: Zack Weinberg traîte souvent une technique de "obsolète" même si elle existe encore parce qu'elle a aussi ses avantages.
l'article est de par sa nature une liste de points négatifs, pas un aperçu complet de la situation.
Ben oui, si on a envie de s'amuser à mélanger, voire combiner des macros et des templates
Si, mais pas d'utiliser des noms de paramètres commençant par des underscores.
Ben, je ne vois pas où se trouve la difficulté en l'utilisation de gcc -E.
Et je n'insinuais rien de particulier contre toi, c'est juste que beaucoup de personnes ont l'attitude fâcheuse de répondre à mes messages sans aller lire les liens que j'indique.Moi, je suis allé lire le texte alors que tu ne m'as même pas donné d'URL.
Ben, moi, je trouve que oui, le fait que l'article ne montre (volontairement) que les points négatifs et que tu ne vois pas les points positifs en le lisant change quelque chose. Et le fait que l'auteur est quelqu'un qui se plaint plus que les autres de ces problèmes change aussi quelque chose.
nitro
:Si, mais pas d'utiliser des noms de paramètres commençant par des underscores.
Ok, donc si je fais un my_min dans mon code je risque des collisions, ou alors j'ai oublié un détail ?
je n'ai pas donné d'URL parce que je ne sais pas où ça se trouve sur le net
Si tu fais un my_min dans ton code, tu dois quand-même savoir quelles variables ton code utilise, et utiliser une convention par conséquent
Si, mais pas d'utiliser des noms de paramètres commençant par des underscores. (C'est explicitement interdit par les standards C et C++.)