Il semblerait que ce ne sera possible que l'an prochain, alors que la critique est faite cette année.
Ça, c'était pour la mauvaise foi de circonstance :)
Je reconnaît que je ne connaissais pas le futur std::string_view (et je te remercie au passage de m'informer de son existence) mais je citais un cas présent, avec le standard existant.
Toujours est-il que cette nouvelle classe semble méchamment plus intéressante que std::string, il faudra que je regarde de plus près, afin de questionner les choses que je ne comprends pas, pour évoluer au prix de quelques moinssages. Mais tel est le prix de la liberté :)
Donc, mélanger les compilateurs, même si on fait du C ou du "struct&pointers", c'est dangereux.
YOLO… triste, mais… comment dire… tellement vrai.
À l'heure actuelle, il me semble que ce qu'il se fait c'est du travail sur les conventions C (cdecl & co) et ça permets d'avoir des plug-ins qui marchent à peu près. C'est pour ça que la compat C est si importante: c'est elle qui nous permets de causer, c'est notre lien, c'est la langue indoeuropéene des langages informatique.
De là même façon qu'en électronique, il me semble me souvenir que par convention, l'intensité est inversée par rapport aux fait.
Il serait difficile d'imposer un standard par arch de toute façon, parce que qu'il existe plusieurs OS avec des historiques variés (windows NT, *BSD, linux, solaris, whatever).
Maintenant certains constructeurs le font, c'est une bonne chose pour l'interop. Mon avis, c'est que les gouvernements devraient obliger par la loi l'interop, avec des formats standards en fonction du matos (et être compétents, ainsi que mettre force de loi à des standards entre composants histoire qu'on cesse de jeter à l'excès, je m'écarte du sujet).
Disclaimer : je n'y connais rien en C++ donc ce que je vais dire repose essentiellement sur ma compréhension de la documentation de shared_ptr.
Je tenterai de garder ça en mémoire, mais en retour, je te demande de tenter de garder en mémoire que je ne connais du OCaml que ce que j'ai cru comprendre au travers des discussions de linuxfr, c'est à dire quasi rien excepté quelques concepts hyper vagues (car je n'ai pas fait l'effort de m'investir). Si je me trompe, je compte sur toi pour pour me le dire. C'est à ça que sert un forum technique en même temps.
Ai-je bien compris le concept de shared_ptr
Je pense que non, mais je me trompe peut-être.
Je pense que la confusion viens du fait que les langages fonctionnels semblent (de ce que j'ai compris) favoriser la copie lors d'écriture et être optimisés pour ça. Ils masquent les mécanismes de bas niveau.
Le shared_ptr de c++ n'est rien d'autre qu'une zone mémoire qui est partagée entre plusieurs autres objets, et chacun peut y modifier les données. Jusque la, ça va encore.
Les problèmes:
les autres propriétaires du shared_ptr n'ont aucune idée de la taille de la zone allouée.
je ne crois pas qu'il y ait moyen de savoir si les données sont valables dans le cas d'un traitement multi-thread/process, car ce n'est vraiment qu'un fichu stupide pointeur!
en admettant que l'on réussisse à contourner ces problèmes, j'attend encore de voir un code maintenable qui exploite cette fonctionnalité. Les standards décrivent ce que l'on peut faire, pas ce que l'on devrait faire, il est important pour moi de garder un esprit critique, même en étant moins intelligent que les gens qui font les standards.
sensibiliser à la problématique de la centralisation d'Internet ;
J'ai un point de vue personnel et peut-être éventuellement technique sur la question, qui fait que comprend pourquoi vous trouvez ça dangereux.
Du coup, si vous pouvez m'aider a avoir des pistes pour dire en quoi c'est une mauvaise chose qu'internet soit centralisé, et comment faire pour l'empêcher, avec en prime un impact négatif négligeable sur le coût financier (au moins technique, l'humain, ça peut se gérer je pense, en fonction de la situation) je vous serais reconnaissant.
Je ne dis pas que je ne suis pas reconnaissant envers framasoft.
Loin de là: vous hébergez l'un des sites qui m'on permis de passer d'un windows full propriétaire/cracké à un windows libéré. Je ne l'ai jamais dis, et je sais que c'est un tort car ça réchauffe le cœur, mais sachez que c'est en partie grâce à vous que:
je moule ici. Par une référence, certes.
j'ai eu un environnement de développement libre sous windows.
j'ai eu un bureau quasi libre sous windows.
je suis passé à Debian.
je suis capable de ne pas changer de PC tous les 3 ans.
je contribue de temps en temps, en code, à divers projets.
Je sais que la plupart de mon entourage n'en fera pas autant que moi, parce qu'ils n'auront pas les compétences, parce qu'ils ne considéreront pas que ça vaut le coup, etc.
Mais, ce que je trouverais utile, en plus de fournir des services utiles et d'essayer d'essaimer, c'est que vous nous enseigniez, à nous qui sommes d'accord avec vous, comment convaincre voire, pourquoi pas, persuader, nos proches d'adopter ces solutions, que ce soit en utilisant vos services ou des chatons.
Parce que mon avis, c'est que c'est ça qu'il nous manque: le savoir convaincre, et le savoir persuader (l'un et l'autre s'adressant à des catégories différentes).
Je suis d'accord, ce n'est pas possible et même probablement pas souhaitable d'avoir un truc unifié multi-arch.
Ceci étant dit, le mangling, justement, est ce qui force à repasser en mode "struct&pointers" quand on veut faire joujou avec des plug-ins, et l'on n'est même pas sûr que d'un compilateur à l'autre, voire d'une version à l'autre d'un même compilo, il ne faille pas tout recompiler.
Après, les exceptions… personnellement, j'évite, et si j'utilise, je ne les fais pas sortir de leur binaire. D'une part, je trouve pas ça si terrible que ça en terme de maintenance, et d'autre part, si une exception n'est jamais rattrapée, c'est un comportement indéfini, et comme elles ne sont pas toujours super documentées… je ne les hais pas, je m'en méfie juste.
mais c'est sans doute plutôt un manque de temps-développeurs qui explique ce retard.
Manque de temps qui à priori n'était pas facilité par l'absence de version stable à long terme.
En lisant le journal, je me suis justement dit que la grosse nouveauté était d'avoir une version qui sera maintenue officiellement pendant 18 mois: je suis certain que les mainteneurs Debian vont apprécier le geste.
Et puis pour revenir au C++, les on-dits et ce genre de dépêche ont un effet assez dissuasifs sur moi. Je suis plutôt à l'aise en C
Je vais en profiter pour parler de ce que j'apprécie dans le C++, ça changera du thread ou les défauts sont listés :)
Pour moi, les principaux avantages du C++ sur le C (qui à été mon 1er «vrai» langage), c'est qu'il permets d'automatiser plus le code source, sans forcément avoir recours à des trucs capilo-tractés. Certes, on peut faire des trucs complexes, mais tout ne l'est pas.
Typiquement, les 3 (5 en fait, si on compte le const_cast et le cast old school qui est toujours valide) casts de C++ ont un gros avantage sur celui du C, ils permettent d'éviter pas mal de bugs.
J'ajouterais en 2ème position les template.
Pas la STL (la STL, c'est un concentré de C++: classes, templates, exceptions), juste les templates (la SL possède de beaux exemples comme std::sort déjà mentionné) qui permettent de quasi-supprimer les macros, tout en permettant un code plus lisible et plus sûr (les types sont vérifiés à la compilation). Malheureusement, je ne crois pas (mais je n'ai pas vérifié) qu'il soit aussi simple de manipuler des chaînes de caractères de la même manière en template qu'en macros, donc ces derniers ont toujours leur utilité ( ## et #, même si c'est illisible, m'on déjà été utiles ).
Par exemple, j'ai un template qui permets de caster d'un type vers un autre, et si il y a dépassement (enfin, j'ai pas fait une couverture de test à 100% et j'ai testé que sur des pointeurs et des entiers), ça fait assert ratée. En release, ça ne fait que dalle. Accessoirement, il est plus court à taper que static_cast ;)
J'aurai sûrement pu coder ça à coup de macros, mais je pense que j'aurai dépassé la 60aine de lignes (et j'aime bien aérer en hauteur).
En 3ème position, les fonctions à l'intérieur des structures, plus clairement: les constructeurs et destructeurs: fini de devoir se rappeler d'appeler SDL_FreeFooBar(ptr);.
Contrairement à l'idée reçue, pas besoin d'exceptions ni d'héritage pour en tirer bon profit. Dans le cas de l'héritage, je dirais même que c'est de toute façon un truc que j'évite, comme probablement pas mal de monde et ce, dans tous les langages.
En standard, on a std::unique_ptr, mais, ça ne gère que les pointeurs (et ce n'est pas le seul reproche que j'ai envers unique_ptr, mais comme je l'ai dis, je ne considère pas la STL comme le principal point fort de C++, au risque de me faire descendre :)): pas les resources indexées (handles de fichier, de ressources OpenGL, whatever). Du coup, j'ai une classe qui gère l'unicité des ressources, et qui sait que -1, c'est l'équivalent de nullptr. Enfin, en réalité, elle ne le sait pas: je lui ai collé un paramètre template pour indiquer quelle valeur est équivalent d'une ressource vide.
4ème: la SL. C'est à dire la bibliothèque standard sans les conteneurs. Je ne dis pas qu'ils sont inutiles, mais ils ont les «inconvénients»:
de lancers des exceptions (et on peut pas faire autrement) dans différents cas.
de ne pas permettre de contrôler facilement l'usage mémoire (sauf std::array et, dans une moindre mesure, std::vector. std::map/set et leurs versions multi sont souvent implémentées en RBtree, pas sûr pour les unordered, et de toute façon le standard n'impose rien me semble).
En revanche, la SL, c'est des algo plus ou moins classiques et complexes à faire qu'on peut utiliser d'une ligne. Enfin, surtout depuis c++11, parce qu'avant les lambda et std::begin()/std::end() c'était un peu pénible :)
Le reste, pour moi, ce sont des plus, mais pas les killer features du C++ (surtout du point de vue d'un dev C, j'imagine):
Quand t'as la flemme de faire tes propres conteneurs, tu peux utiliser la STL.
Et si t'as envie de faire tes conteneurs (genre un ring buffer ou un dictionnaire dont on peut connaître l'usage mémoire), mais que tu ne veux pas réécrire les algorithmes standards, tu as juste à implémenter un itérateur: tu bénéficies toujours des algo de la SL.
Bien sûr, le récent fait de pouvoir utiliser les algo sur des tableaux C-style est bien pratique, ainsi que le range for (peut-être qu'il existe aussi en C11? Je ne sais pas du tout ce qu'ils ont ajouté.).
Et pour finir, les exceptions et les flux: beaucoup les aimes, d'autres non, mais dans certains tout ça est bien utile.
En conclusion: tu devrais essayer. Juste, dans un premier temps, remplacer gcc par g++ (ou clang par clang++ ou… bref) et les casts. C'est plus verbeux c'est vrai, mais ça réduit les problèmes.
Puis avec les templates et la RAII, tu te retrouves déjà avec des codes bien plus réduits que leurs versions C, sans être obligé de libérer explicitement les instances de BDD (chose qu'il faut faire manuellement tant en C qu'en Java si on se méfie du côté aléatoire du GC) et sans forcément avoir un code plus dur à lire, même s'il est vrai que plus on combine de techniques, plus le code deviens délicat à manipuler. D'où l'intérêt d'intégrer les avantages au fur et à mesure (et avec le temps de considérer certains morceaux comme peu utiles en regard des services rendus).
(par exemple, pourquoi les destructeurs ne sont-ils pas virtuels par défaut?)
Parce que la présence d'une méthode virtuelle implique la génération d'une vtable, qui a un impact sur les performances.
typiquement, les arguments de main
Portabilité & Compatibilité (oui, je sais) avec la famille execXY() standardisée par POSIX (ne pas oublier que la portabilité est importante pour les utilisateurs de C++).
Tu proposes quoi?
De renvoyer un bool et d'avoir un std::vector<std::string>const& en entrée?
Ça implique argc + 1 appels à new (puisqu'il faudrait copier ce que l'OS envoie, ces conteneurs n'étant pas capables de prendre la propriété d'un pointeur) pouvant throw en cas de problème mémoire. Et ou tu catch, puisque ça à throw avant même d'entrer dans le code?
Je ne mentionne pas le fait que std::string, c'est potentiellement 24 octets par objet (en plus du contenu, tu as en gros un pointeur vers les données, un vers la fin de la zone utilisable et un dernier qui indique la fin réelle. 3 * 8 sur une machine 64bits classique).
Si t'as en entrée un truc genre apt-cache pkgnames, ça risque de faire pas mal de mémoire (45237 entrée chez moi, autrement dit plus d'1Mio potentiels une fois *24. Je dis potentiels, parce qu'avec les SSO ça peut être moins, en fonction du compilo.) et de risques de throw, le tout pour faire plaisir à des gens qui n'ont rien à faire de la performance et de la portabilité, qui ne sont pas la cible première de C++?
Quel réel avantage y aurait-il? Au passage, std::basic_string<char> ou std::basic_string<wchar> (bon, j'ai un doute, je sais plus si c'est wchar ou wchar_t…)?
(personnellement, j'aime bien le comportement d'un bool qu'on a oublié d'initialiser)
Au moins n'est-il pas null, nil, nul ou whatever truc qu'on peut voir ailleurs. Ici, tu oublies un truc: en C++ on ne paye pas pour ce qu'on n'utilise pas. Et ce n'est pas toujours utile d'initialiser tes variables quand tu les déclares: par exemple une variable qui sera initialisée dans une boucle, et utilisée après la fin de cette boucle, il n'y a aucune raison de l'initialiser avant.
Au passage, ton compilo te préviendra pour 99% des cas (jusqu'à présent, il m'a toujours prévenu, mais bon, je laisse place à l'incertitude).
Il y a des gens qui "#include" des trucs autres que des .h?.
La plupart des développeurs C++.
Les fichiers de la SL n'ont pas d'extensions. Pas mal de libs utilisent ".hpp". On voit régulièrement ".tpp" pour les templates. Entres autres.
Mais honnêtement, ça ne me gênerait pas outre mesure que l'on ne soit plus obligé de se taper les header guards, bien au contraire.
Y compris dans la justification de la non-dépréciation de syntaxes obsolètes qui n'ont aucune justification (goto, void*, etc)
Hum. Goto, parce que tu le remplaces par les exceptions, c'est ça? Le support des exceptions augmente, selon un document que j'ai la flemme de rechercher, le binaire d'environ 10%. Pas forcément possible pour tout le monde. void*, ça nous permets de nous interfacer avec du C, avec des fonctions aussi «obsolètes» que dlopen.
Autant je te rejoins sur les header guards, autant pas sur les goto/void* (alors que je n'utilise pas goto et que je ne suis que client de void*).
Il y a du code de 40 ans qui compile grâce à ces trucs? Qu'est-ce qu'on s'en fout
C'est un point de vue. Pas celui de tout le monde.
Ce qu'on peut reprocher au C++, c'est de ne même pas définir la manière correcte de faire les choses
Java à interdit aux dév. de faire des fonctions. Résultat, ils font des classes statiques. Toutes les exceptions doivent être rattrapées? Ok, mais on ne fais rien.
Je parle de Java ici, mais c'est juste le 1er exemple qui me viens en tête. Quand un langage limite ses utilisateurs, ils contournent les limitations, parfois à bon escient (la classe statique, avec le main statique) parfois non (les exceptions) et dans tous les cas, je trouve que ça alourdit la lecture.
C++ n'est pas parfait niveau simplicité de lecture (surtout quand on lit du code template) mais j'apprécie qu'il ne me force pas à suivre une école de pensée unique, qui ne sera pas optimale pour certains cas particuliers.
L’usage d’une fonction clone est problématique aussi (qu’est censé faire Derived::clone(Base const& b) si on lui donne un Base& qui est de type Derived2 ? Un assert ? pas terrible…).
Je n'utiliserais pas la même signature moi, je ferai plutôt static bool Derived::clone( Base const& b, Derived& a ); du coup, tu fais ce que tu veux quand ça échoue, avec a qui n'est pas modifié si tu as fais les choses bien.
Personnellement, j'opte de plus en plus souvent pour l'usage de constructeurs nommés (static foo::make( ... );) et quand ça rate (paramètre foireux, initialisation impossible, whatever), selon mon API je throw ou retourne foo().
C'est un idiome plutôt pratique, qui peut palier à ton problème (si je l'ai bien compris) et même permettre d'avoir plusieurs «constructeurs» avec les mêmes signatures, exemple (bidon) si tu veux générer un pixel RGB, tu peux avoir 3 constructeurs nommés pour faire les nuances d'une couleur unique.
En bonus, dans certains cas, ça évite de se taper les operator= & Ctors, alors que l'on veux juste ajouter un moyen de convertir un type dans un autre. En malus, je "perds" une partie des conversions automatiques (enfin, surtout parce que j'ai souvent la flemme de me tapper les operator=&Ctors).
Le truc, c'est que le C est un langage tellement simple (pas d'héritage, donc pas de méthodes virtuelles donc pas de vtable, pas de RTTI, pas d'exceptions) que c'est relativement simple d'avoir des ABI compatibles (je ne dis pas qu'elles le sont toujours) entre divers fournisseurs.
C'est d'ailleurs pour ça que tout le monde passe par le C pour discuter les uns avec les autres.
Pour les autres langages, souvent plus riches en fonctionnalités, je dirais qu'il y a 2 cas:
Si on prend un langage «propriétaire», non pas dans le sens code source fermé mais dans le sens qu'il n'existe qu'un compilo et que c'est lui la norme, le problème se résous de lui-même.
Mais dans le cas d'un langage comme C++ (doit y en avoir d'autres je pense), qui est un standard ISO pouvant être implémenté par de nombreux acteurs et sur tout type de matériels, le fait de ne pas avoir d'ABI standardisée (dans les spec. du langage) me semble être un pré-requis, pour la faisabilité (diversité des acteurs, code fermé & P.I., etc.) comme pour les possibles optimisations dépendant des architectures. Enfin, pour les optimisations, c'est ce que je me suis laissé dire: n'y connaissant pas grand chose, je ne peux juger.
D'une part, j'ai bien précisé: "je pense", je n'ai pas dit "c'est une erreur". La nuance est faible, mais existante: je n'ai jamais prétendu être bon, donc je peux penser des conneries.
Ceci étant dit, j'ai beaucoup de mal avec l'idée qu'un objet soit possédé par plusieurs autres à la fois, en terme de maintenance j'imagine mal ça simplifier les choses.
D'ailleurs, c'est assez amusant. Je me rappelle qu'au début je trouvais l'idée super. J'ai réfléchi à l'utiliser sans jamais y trouver d'usage mais je me disais juste que l'occasion ne s'était pas présentée. De fil en aiguille j'étais tombé sur un billet de blog ou l'auteur expliquait pourquoi il estimait que l'utiliser ne lui semblait pas une bonne idée. J'ai essayé de répondre à ses points (vu que je n'étais pas d'accord du tout), et, en répondant, je me suis aperçu que tous les arguments que j'avais en faveur du shared_ptr étaient mauvais. Du coup j'ai bien du passer 2H à ne rien répondre.
Après, peut-être qu'un jour je tomberai sur un cas d'usage réel, après tout, j'ai bien eu une fois un cas ou l'héritage en diamant m'a été utile (je ne dirai pas que ce cas était super bien ficelé, mais dans la situation c'était ça ou duplication d'une quantité de code assez conséquence comparé à la taille du projet)…
Pour conclure, je veux bien un cas d'usage quotidien de shared_ptr. Si je peux être détrompé, tant mieux.
beaucoup de monde joue avec des sources qui sont en C++03, donc au revoir les smart-pointers.
Non, au revoir la move semantic, et donc au revoir std::unique_ptr.
Mais std::auto_ptr (maintenant déprécié car remplacé par unique_ptr qui est plus sûr, certes) existait déjà en C++03. Et c'était toujours mieux que d'utiliser des raw, mais personne ne l'utilisait. Probablement parce que, par exemple, les gens qui enseignent ne connaissaient pas nécessairement son existance (j'en ai jamais entendu parler à l'école, des pointeurs intelligents… de manière générale, on à très peu parlé de la lib standard, je ne sais vraiment pas pourquoi, ça aurait réduit pas mal certaines conneries).
Et pour ce qui est de shared_ptr, je pense que ce truc est une erreur, mais bon, un pointeur intelligent avec compteur de référence ce n'est pas ce qu'il y a de plus difficile à coder non plus.
Enfin, tant qu'on reste dans le mono-threadé ou si l'on accepte d'utiliser des libs externes: le multi-thread était inexistant avant C++11 après tout.
Ici, ça me semble clair: c'est B qui définit qui à le droit d'utiliser ses propriétés protégées. Le fait que D considère fr() comme une amie ne donne absolument pas le droit à fr() d'utiliser une propriété protégée de B, uniquement celles de D.
Donc pour moi, g++ à tort et clang++ raison. Et je doute que le standard ait changé sur ce point: il faudrait trouver un vieux compilo standard de l'époque pour etre sur.
Ceci dit, personne n'a dis que le C++ n'était pas trop compliqué. C'est de notoriété commune (et en plus maintenant on multiplie les façons de gérer un prototype de fonction avec le auto foo() ->type).
Une fois ajouté la dessus le fait que certains compilos vont ajouter silencieusement leurs tolérances et extensions si tu ne précises pas un standard, et tu multiplies les risques de confusion, sur un truc déjà complexe.
Tout est dans le titre, surtout si tu n'as que 2 ans pour refaire ton application.
Au final, ce qui importera probablement le plus, ce sera ta conception, le langage ne sert pour moi qu'a traduire.
Pour un soft de gestion, le plus gros sera fait par la BDD, et elles offrent toutes des bibliothèques utilisables dans tous les langages un minimum populaires (et pour les autres, il faut adapter la lib C, mais bon…). Tu peux aussi utiliser des technologies qui permettent de requêter n'importe quel SGBDR avec une seule lib, je ne sais plus comment elle s'appelle mais il y en a au moins une.
Bon, après, si tu es rouillé, je dirais évites le C, tu te prendra la tête pour pas grand chose (gestion des ressources (RAM, mais aussi connections à la BDD ou identifiants des fenêtres graphiques) manuelle, si tu oublies un truc tu as un crash ou pire, un bug longtemps après).
Ceci étant dit, je me pose la même question que d'autres: avant de coder, pourquoi ne pas regarder l'existant auquel tu peux avoir accès?
Je doute que tu aies des besoins transcendants après tout (si je comprend bien, tu as une petite structure) et partir d'un existant sera probablement bien plus léger en terme de charge. Sans parler du fait qu'un existant a une communauté déjà en place, tu n'aurais pas besoin de faire toute la maintenance tout seul.
Je pense notamment à dolibarr, qui a fait l'objet de plusieurs dépeches ici, mais il y en a probablement d'autres.
Swift n'a pas de gc. Arc est pure compile time, et 100% déterministe.
Ok. Faudra que j'y jette un oeil.
Comme pour du c++ de 1995 dans un projet c++17.
Dis-moi, tu as remarqué que j'ai parlé de C++ standard, et donc de 98?
As-tu aussi remarqué que je parlais de prendre un code source du vieux standard et de le compiler avec un compilateur moderne?
Si tu réponds oui, alors donne moi un bout de code répondant au 1er standard C++, c'est à dire de 1998 (donc, non, pas de 1995…) que je ne puisse pas compiler avec, par exemple, clang3.8.
Quant au C++17, vu qu'il n'est pas encore sorti, ça va être difficile de tester.
Et encore, même Java, ton code tu vas vouloir le moderniser.
Tout à fait. Mais pour moderniser, il faut encore être capable de compiler l'original.
Imaginons un peu, tu tombes un jour sur un logiciel open source sympa mais plus maintenu depuis 10-15 ans (allez, genre, autorealm. J'aimerai vraiment arriver à le recompiler lui… mais c'est du delphi, et je me sens pas motivé pour acheter une licence windows + whatever compilo juste pour moderniser et porter ce logiciel sous linux).
Le fait de pouvoir le compiler malgré l'absence de mise à la modernité pendant plus d'une décenie est un peu vital pour pouvoir le moderniser ensuite sans reprendre tout le code source.
C'est une des choses que je pense que C++ permets.
mais j'ai de plus en plus tendance à passer à Python+PyQt pour les GUI et interfacer avec un backend à plus hautes performances.
Je comprend.
On ne pourra pas passer par du C++ (ou n'importe quel autre langage qui utilise autre chose que pointeurs + types machines) tant qu'une ABI n'aura pas été définie ;
C'est du C++ parfaitement valide. L'ABI est stable, bien que j'aie un doute sur le fait que ce soit par convention ou par standard.
Le fait est que, bien sûr, il faut se débarasser de la totalité des fonctionnalités C++ dans l'API, mais bon… je pinaille, j'avoue :)
En tout cas, j'en retire que ce que tu fais avec python+rust, tu peux le faire avec python+C++.
En ce qui concerne Rust, il a une FFI plutôt correcte avec le C
Je ne suis pas expert, mais j'ai l'impression que c'est un peu la meme chose partout, de ce point de vue la. Enfin, non, puisqu'en C++, justement, il n'y a pas besoin d'autant de colle.
Objectivement, je dirais avantage à C++ en terme de quantité de code vital pour importer du code C, et pour cause, un sous-ensemble du C++ est entièrement compatible avec le C (mais pas l'inverse, parce qu'il me semble que le C++ réserve certains mots non réservés par le C, genre public).
Enfin, ce genre de trucs me rappelle la fois ou j'avais du interfacer du C++ avec powerbuilder12… j'avais fini par pondre un wrapper complet, qui permettait avec quelques macros (non nécessaires elles, mais ça réduisait méchamment le boilerplate) et beaucoup de template, histoire d'etre sur que quand ça plantait ça venait pas de la colle powerbuilder/C++… foutu langage proprio de merde, si tu veux mon avis.
Existe-t-il un langage qui empêche complètement les erreurs catastrophiques? Qui n'expose jamais au risque de perdre des données, qui génère des programmes dont on est sûrs à 100% qu'ils ne planteront jamais?
A priori, ADA pourrait coller à la description, mais, je ne l'ai pas vu cité encore. J'ai vu cités Swift, Go, et d'autres dont je n'ai jamais entendu parler. Ceux-la, ils y collent à la description? Et en pratique, ça donne quoi?
temps de compilation ;
Faut dire que, quand on voit le code le STL de g++, on comprend que ce soit long à compiler… ça s'include dans tous les sens, avec des macros en veux-tu en voila, des héritages et aggrégations tortueux… et de manière générale un code illisible (chose amusante: ils indentent parfois avec des espaces, parfois avec des tabulations. Je ne parle pas d'aligner le code, mais bien de l'indentation!).
Je n'ai pas fait de comparaisons sur les temps de compilations, mais depuis quelques temps j'utilise libc++ de llvm. Rien que pour comprendre pourquoi un truc merde, c'est 10 fois plus simple (même si je reste gêné par le fait qu'il soit impossible d'interdire au compilo les inline quand on debug…).
Au final, j'utilise clang parce que plus rapide et plus clair que gcc depuis plusieurs années, et cette année j'ai commencé à utiliser leur STL.
Plus ça va, moins j'utilise d'outils GNU pour le dev, et mieux je me porte. Ca ne m'empêche par de reconnaître que je leur dois une fière chandelle, hein, mais je pense que certains défauts repprochés au langage C++ sont plus dus aux outils libres «standards de facto» qu'au langage lui-même. Ou du moins, que ces fameux outils sont une cause aggravante. Le poids de l'historique, sûrement.
Ah oui, j'oubliai: j'essaie aussi de tendre vers l'utilisation de musl, histoire qu'on me dise pas que j'ai oublié la libc :) (mais bon, oui, il me reste pas mal de trucs à remplacer, faut du temps, surtout que je fais ça pour le fun surtout).
le langage de templates qui est parmi les plus abscons, parce qu'il mélange les génériques et la métaprogrammation (ou alors je suis le seul à trouver les templates récursifs imbitables) ;
Existe-t-il un autre langage natif ayant un mécanisme de templates aussi puissant que celui du C++, et qui offre les mêmes perfs (à peu près, du moins)?
Rust, peut-être? (vraie question)
le préprocesseur, vraiment ?
Malheureusement, on en a besoin pour pouvoir utiliser des trucs codés en C. Dans certains cas, ça permets aussi de réduire le code boiler-plate.
Mais, c'est vrai: ce truc est un générateur de galères, quand il est utilisé abusivement. Les fonction inlinées sont par exemple bien plus intéressantes que les macros (surtout en combinaison avec les template), et pourtant dans certains bouts de code on voit encore des macros.
La dernière fois que j'ai vu des macros utilisées, c'était soit dans du code C, soit dans des framework de test, cela dit.
Reste donc que l'usage d'import de header, et je suis d'accord pour dire que ça serait pas mal qu'il saute.
(pourquoi on ne peut pas définir une classe template ailleurs que dans son header ?)
Tu peux. Il suffit qu'elle soit déjà définie quand elle est utilisée. Ca m'arrive de faire des petites structures templates internes à un fichier, que je n'expose pas publiquement ça aucun intérêt.
Je me doute que tu le sais, mais ce n'est pas nécessairement le cas de tous, je me permets donc cette clarification :)
'évolution rachitique
Vrai. C'est lent.
Je me demande quelle est la part de responsabilité liée à l'ISO, ceci dit. La plupart des langages qui sortent, au final, n'ont qu'une implémentation de référence, pas de normalisation réelle.
Hors, cette standardisation officielle et internationale est une force de C++ pour moi.
Du coup, je comparerai la lenteur d'évolution de C++ à Debian: c'est lent et vieux, c'est vrai, mais le fait que ça n'aille pas trop vite semble avoir pour conséquence que la maintenance est plus simple pour les utilisateurs (un vieux code C++ compile sur un compilo moderne sans trop de soucis, et une Debian peut être up/down gradée de la même manière). Pas la création d'un système fonctionnel, sa maintenance, j'insiste.
la gestion mémoire qui accumule plusieurs couches au fil des années (pointeurs nus, références, puis pointeurs intelligents [unique_ptr/shared_ptr/etc.]) ;
Marrant, c'est justement pour la gestion de la mémoire que j'apprécie le C++. Parce qu'en C++, si je veux utiliser un GC, je peux. Si je veux utiliser des pointeurs intelligents, je peux. Si je veux utiliser des pointeurs nus, je peux encore!
J'ai le choix, bon sang, et c'est bien d'avoir le choix, de la meme manière que c'est bien de pouvoir choisir entre windows, mac OS, Debian, voidlinux, FreeBSD, OpenBSD, etc.
C'est perfectible, bien sûr, mais quand je lis qu'il est obligatoire d'utiliser des pointeurs nus en C++, je comprend que l'auteur de la phrase lue ne connaît pas le C++ (je ne dis pas l'avoir lue ici, mais j'ai déjà lu ça, plus d'une fois).
Sincèrement, avec la STL, les références et les itérateurs, les pointeurs nu ne sont simplement qu'une façon de s'interfacer avec le C ou les vieilles bibliothèques. Rien de plus.
A noter un repproche que je fais aux pointeurs intelligents standard: ils ne savent gérer que la mémoire, alors que ce n'est qu'une seule des ressources que l'on peut manipuler (alors qu'un descripteur de fichier UNIX est un int, par exemple). Sans parler du fait qu'ils aient un overhead pour moi inutile (évident pour shared_ptr, moins pour unique_ptr, mais le fait est qu'un pointeur pour stocker l'@ du destructeur est maintenu et testé, alors que ça aurait pu être passé en template. Mais j'imagine que certains ont l'usage de modifier le destructeur au runtime?).
Maintenant, oui, je l'admets: utiliser des références ou des itérateurs ne protège pas contre les segfaults, et il n'y a rien à ma connaissance en C++ pour gérer ça. C'est un des points qui font que je veux me mettre à Rust, un jour.
Le C++ ne permets pas non plus, à ma connaissance, de vérification sur les under/over-flow d'entier. C'est un problème, pour moi, vraiment. D'un autre côté, ça permets un code plus léger et plus rapide, parce que si à chaque addition on devait faire une vérification à l'exécution, c'est du code en plus à exécuter, de la lenteur.
Ce que j'apprécierai vraiment, ça serait de pouvoir faire ça, uniquement pendant le debug.
mais pas de vector::delete_at)
Et ça n'arrivera jamais, j'espère. Si une telle fonction devait exister, elle aurait plutôt sa place dans les algorithmes, autrement dit, ce serait std::delete_at( iterator it, container& cont ); ou un truc de goût là.
Les APIs de la STL sont déjà assez moyennes comme ça, à mon avis (à la fois trop riches et pas assez: trop riches parce que, par exemple, std::vector::insert pourrait être implémenté en dehors du conteneur (avec une combinaison de std::move&std::inserter par exemple) alors qu'il est difficile de connaitre le cout mémoire réel d'un conteneur (pour vector c'est faisable, mais pour std::map?) ).
En tout cas, c'est marrant, dans la liste des défauts de la STL, j'aurai pensé voir std::string au moins une fois (parce qu'elle s'interface relativement mal avec le reste de la lib standard, et que pour une gestion de chaine de caractères, ça ne permets meme pas de diviser facilement… bref je la trouve bancale.).
rétro-compatibilité avec le C, mais pas vraiment non plus.
Comme tout les langages sauf le C, en fait. Je pense que l'on devrait arrêter de ce soucier du C, franchement.
Je pense qu'une bonne part des emmerdes du C++ viennent du C.
dont une bonne partie sont ÀMHA imputable à son âge.
Personnellement, si j'apprécie énormément le C++, c'est parce que c'est un langage qui donne le choix.
Il me donne le choix d'utiliser les template.
Il me donne le choix d'utiliser le modèle mémoire que je veux (GC, pointeurs intelligents, pointeurs nu. Bon, ok, pour le GC il n'y a rien dans la lib standard, probablement parce que la culture C++ préfère la RAII).
Il me donne le choix d'utiliser la RTTI (j'inclue dedans les méthodes virtuelles).
Il me donne le choix de faire de l'héritage multiple et même en diamant (ça m'est déjà arrivé une fois de m'en servir).
Il me donne le choix d'utiliser les exceptions (à condition de se passer de la STL, certes).
Rien n'est obligatoire, il faut choisir ce que l'on utilise. Pour certains, c'est un défaut. Pour moi, c'est une force.
Pour refaire le parallèle avec les distributions Linux: pour moi, l'apparition de Devuan, d'Ubuntu, d'Archlinux, et j'en oublie, ce sont de bonnes choses, parce que ça donne le choix.
Alors bien sûr, avoir le choix implique de prendre des décisions, mais pour moi c'est un peu le coeur de métier d'un développeur, de prendre des décisions.
Mais ce n'est pas parce que j'aime beaucoup C++ que je dis qu'il n'a aucun défaut. Seulement, à l'heure actuelle, je ne vois que Rust pour le remplacer, et il est encore jeune, on n'a pas encore eu le temps de voir comment il vieillit.
Avant de dire que Rust peut remplacer C++, il faudra au moins 5 ans d'écart entre la sortie de sa 1ère version stable et l'heure du jugement, justement pour avoir du recul.
On n'a aucun recul sur Rust, contrairement à C++ ou l'on parle de près de 20 ans ( ~18 de standard ISO).
Je ne le nie pas, les temps de compilation C++ peuvent être longs. Ceci étant dit, quelle est la part de lenteur due au langage, et quelle est la part due aux outils, make, par exemple?
Parce que selon certains, pour une compilation incrémentale, make est inutilement très lent.
Et aussi, je pense que comparer uniquement les temps de compilation est une erreur de nos jours. Après tout, si on prend Java ou C#, il me semble bien qu'une partie de la compilation est faite au lancement de l'exécutable.
Du coup, ce qui serait objectif, c'est de comparer compilation + temps de première exécution, non?
Je ne travaille qu'avec Rust, mais je n'ai pas eu pour le moment besoin de GUI. Et si je devais en faire une, je pense que je m'en ferais une en Java/Kotlin/C# interfacé avec le backend Rust.
Intéressant.
Donc ce n'est pas un problème si C++ ne gère pas les GUI, puisqu'on peut aussi interfacer avec du "Java/Kotlin/C#" (même s'il faut passer par du C++ Céifié à cause de l'ABI, mais c'est un autre sujet que l'absence de GUI, et j'ai beau aimer le C++ je sais que le manque d'ABI stable est un véritable problème. Enfin, je ne sais pas comment ça se fait en Rust, non plus).
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 1.
Il semblerait que ce ne sera possible que l'an prochain, alors que la critique est faite cette année.
Ça, c'était pour la mauvaise foi de circonstance :)
Je reconnaît que je ne connaissais pas le futur std::string_view (et je te remercie au passage de m'informer de son existence) mais je citais un cas présent, avec le standard existant.
Toujours est-il que cette nouvelle classe semble méchamment plus intéressante que std::string, il faudra que je regarde de plus près, afin de questionner les choses que je ne comprends pas, pour évoluer au prix de quelques moinssages. Mais tel est le prix de la liberté :)
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.
YOLO… triste, mais… comment dire… tellement vrai.
À l'heure actuelle, il me semble que ce qu'il se fait c'est du travail sur les conventions C (cdecl & co) et ça permets d'avoir des plug-ins qui marchent à peu près. C'est pour ça que la compat C est si importante: c'est elle qui nous permets de causer, c'est notre lien, c'est la langue indoeuropéene des langages informatique.
De là même façon qu'en électronique, il me semble me souvenir que par convention, l'intensité est inversée par rapport aux fait.
Il serait difficile d'imposer un standard par arch de toute façon, parce que qu'il existe plusieurs OS avec des historiques variés (windows NT, *BSD, linux, solaris, whatever).
Maintenant certains constructeurs le font, c'est une bonne chose pour l'interop. Mon avis, c'est que les gouvernements devraient obliger par la loi l'interop, avec des formats standards en fonction du matos (et être compétents, ainsi que mettre force de loi à des standards entre composants histoire qu'on cesse de jeter à l'excès, je m'écarte du sujet).
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.
Je tenterai de garder ça en mémoire, mais en retour, je te demande de tenter de garder en mémoire que je ne connais du OCaml que ce que j'ai cru comprendre au travers des discussions de linuxfr, c'est à dire quasi rien excepté quelques concepts hyper vagues (car je n'ai pas fait l'effort de m'investir). Si je me trompe, je compte sur toi pour pour me le dire. C'est à ça que sert un forum technique en même temps.
Je pense que non, mais je me trompe peut-être.
Je pense que la confusion viens du fait que les langages fonctionnels semblent (de ce que j'ai compris) favoriser la copie lors d'écriture et être optimisés pour ça. Ils masquent les mécanismes de bas niveau.
Le shared_ptr de c++ n'est rien d'autre qu'une zone mémoire qui est partagée entre plusieurs autres objets, et chacun peut y modifier les données. Jusque la, ça va encore.
Les problèmes:
# sensibilisation à la centralisation?
Posté par freem . En réponse à la dépêche Six nouveaux services chez Framasoft (30 au total). Évalué à 7.
J'ai un point de vue personnel et peut-être éventuellement technique sur la question, qui fait que comprend pourquoi vous trouvez ça dangereux.
Du coup, si vous pouvez m'aider a avoir des pistes pour dire en quoi c'est une mauvaise chose qu'internet soit centralisé, et comment faire pour l'empêcher, avec en prime un impact négatif négligeable sur le coût financier (au moins technique, l'humain, ça peut se gérer je pense, en fonction de la situation) je vous serais reconnaissant.
Je ne dis pas que je ne suis pas reconnaissant envers framasoft.
Loin de là: vous hébergez l'un des sites qui m'on permis de passer d'un windows full propriétaire/cracké à un windows libéré. Je ne l'ai jamais dis, et je sais que c'est un tort car ça réchauffe le cœur, mais sachez que c'est en partie grâce à vous que:
Je sais que la plupart de mon entourage n'en fera pas autant que moi, parce qu'ils n'auront pas les compétences, parce qu'ils ne considéreront pas que ça vaut le coup, etc.
Mais, ce que je trouverais utile, en plus de fournir des services utiles et d'essayer d'essaimer, c'est que vous nous enseigniez, à nous qui sommes d'accord avec vous, comment convaincre voire, pourquoi pas, persuader, nos proches d'adopter ces solutions, que ce soit en utilisant vos services ou des chatons.
Parce que mon avis, c'est que c'est ça qu'il nous manque: le savoir convaincre, et le savoir persuader (l'un et l'autre s'adressant à des catégories différentes).
[^] # Re: Ne te prend pas la tête
Posté par freem . En réponse au journal Comment distribuer un logiciel pour GNU/Linux ?. Évalué à 1. Dernière modification le 06 octobre 2016 à 09:31.
Oups, pas vu qu'il y a la même réponse un peu plus haut…
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 1.
Je suis d'accord, ce n'est pas possible et même probablement pas souhaitable d'avoir un truc unifié multi-arch.
Ceci étant dit, le mangling, justement, est ce qui force à repasser en mode "struct&pointers" quand on veut faire joujou avec des plug-ins, et l'on n'est même pas sûr que d'un compilateur à l'autre, voire d'une version à l'autre d'un même compilo, il ne faille pas tout recompiler.
Après, les exceptions… personnellement, j'évite, et si j'utilise, je ne les fais pas sortir de leur binaire. D'une part, je trouve pas ça si terrible que ça en terme de maintenance, et d'autre part, si une exception n'est jamais rattrapée, c'est un comportement indéfini, et comme elles ne sont pas toujours super documentées… je ne les hais pas, je m'en méfie juste.
[^] # Re: Stabilité qui a pris du temps ?
Posté par freem . En réponse à la dépêche KDE Plasma 5.8 LTS. Évalué à 3.
Manque de temps qui à priori n'était pas facilité par l'absence de version stable à long terme.
En lisant le journal, je me suis justement dit que la grosse nouveauté était d'avoir une version qui sera maintenue officiellement pendant 18 mois: je suis certain que les mainteneurs Debian vont apprécier le geste.
[^] # Re: Jai: Language for game programmming
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 7.
Je vais en profiter pour parler de ce que j'apprécie dans le C++, ça changera du thread ou les défauts sont listés :)
Pour moi, les principaux avantages du C++ sur le C (qui à été mon 1er «vrai» langage), c'est qu'il permets d'automatiser plus le code source, sans forcément avoir recours à des trucs capilo-tractés. Certes, on peut faire des trucs complexes, mais tout ne l'est pas.
Typiquement, les 3 (5 en fait, si on compte le const_cast et le cast old school qui est toujours valide) casts de C++ ont un gros avantage sur celui du C, ils permettent d'éviter pas mal de bugs.
J'ajouterais en 2ème position les template.
Pas la STL (la STL, c'est un concentré de C++: classes, templates, exceptions), juste les templates (la SL possède de beaux exemples comme std::sort déjà mentionné) qui permettent de quasi-supprimer les macros, tout en permettant un code plus lisible et plus sûr (les types sont vérifiés à la compilation). Malheureusement, je ne crois pas (mais je n'ai pas vérifié) qu'il soit aussi simple de manipuler des chaînes de caractères de la même manière en template qu'en macros, donc ces derniers ont toujours leur utilité ( ## et #, même si c'est illisible, m'on déjà été utiles ).
Par exemple, j'ai un template qui permets de caster d'un type vers un autre, et si il y a dépassement (enfin, j'ai pas fait une couverture de test à 100% et j'ai testé que sur des pointeurs et des entiers), ça fait assert ratée. En release, ça ne fait que dalle. Accessoirement, il est plus court à taper que
static_cast
;)J'aurai sûrement pu coder ça à coup de macros, mais je pense que j'aurai dépassé la 60aine de lignes (et j'aime bien aérer en hauteur).
En 3ème position, les fonctions à l'intérieur des structures, plus clairement: les constructeurs et destructeurs: fini de devoir se rappeler d'appeler
SDL_FreeFooBar(ptr);
.Contrairement à l'idée reçue, pas besoin d'exceptions ni d'héritage pour en tirer bon profit. Dans le cas de l'héritage, je dirais même que c'est de toute façon un truc que j'évite, comme probablement pas mal de monde et ce, dans tous les langages.
En standard, on a std::unique_ptr, mais, ça ne gère que les pointeurs (et ce n'est pas le seul reproche que j'ai envers unique_ptr, mais comme je l'ai dis, je ne considère pas la STL comme le principal point fort de C++, au risque de me faire descendre :)): pas les resources indexées (handles de fichier, de ressources OpenGL, whatever). Du coup, j'ai une classe qui gère l'unicité des ressources, et qui sait que -1, c'est l'équivalent de nullptr. Enfin, en réalité, elle ne le sait pas: je lui ai collé un paramètre template pour indiquer quelle valeur est équivalent d'une ressource vide.
4ème: la SL. C'est à dire la bibliothèque standard sans les conteneurs. Je ne dis pas qu'ils sont inutiles, mais ils ont les «inconvénients»:
En revanche, la SL, c'est des algo plus ou moins classiques et complexes à faire qu'on peut utiliser d'une ligne. Enfin, surtout depuis c++11, parce qu'avant les lambda et std::begin()/std::end() c'était un peu pénible :)
Le reste, pour moi, ce sont des plus, mais pas les killer features du C++ (surtout du point de vue d'un dev C, j'imagine):
Quand t'as la flemme de faire tes propres conteneurs, tu peux utiliser la STL.
Et si t'as envie de faire tes conteneurs (genre un ring buffer ou un dictionnaire dont on peut connaître l'usage mémoire), mais que tu ne veux pas réécrire les algorithmes standards, tu as juste à implémenter un itérateur: tu bénéficies toujours des algo de la SL.
Bien sûr, le récent fait de pouvoir utiliser les algo sur des tableaux C-style est bien pratique, ainsi que le range for (peut-être qu'il existe aussi en C11? Je ne sais pas du tout ce qu'ils ont ajouté.).
Et pour finir, les exceptions et les flux: beaucoup les aimes, d'autres non, mais dans certains tout ça est bien utile.
En conclusion: tu devrais essayer. Juste, dans un premier temps, remplacer gcc par g++ (ou clang par clang++ ou… bref) et les casts. C'est plus verbeux c'est vrai, mais ça réduit les problèmes.
Puis avec les templates et la RAII, tu te retrouves déjà avec des codes bien plus réduits que leurs versions C, sans être obligé de libérer explicitement les instances de BDD (chose qu'il faut faire manuellement tant en C qu'en Java si on se méfie du côté aléatoire du GC) et sans forcément avoir un code plus dur à lire, même s'il est vrai que plus on combine de techniques, plus le code deviens délicat à manipuler. D'où l'intérêt d'intégrer les avantages au fur et à mesure (et avec le temps de considérer certains morceaux comme peu utiles en regard des services rendus).
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.
Parce que la présence d'une méthode virtuelle implique la génération d'une vtable, qui a un impact sur les performances.
Portabilité & Compatibilité (oui, je sais) avec la famille
execXY()
standardisée par POSIX (ne pas oublier que la portabilité est importante pour les utilisateurs de C++).Tu proposes quoi?
De renvoyer un bool et d'avoir un
std::vector<std::string>const&
en entrée?Ça implique argc + 1 appels à new (puisqu'il faudrait copier ce que l'OS envoie, ces conteneurs n'étant pas capables de prendre la propriété d'un pointeur) pouvant throw en cas de problème mémoire. Et ou tu catch, puisque ça à throw avant même d'entrer dans le code?
Je ne mentionne pas le fait que std::string, c'est potentiellement 24 octets par objet (en plus du contenu, tu as en gros un pointeur vers les données, un vers la fin de la zone utilisable et un dernier qui indique la fin réelle. 3 * 8 sur une machine 64bits classique).
Si t'as en entrée un truc genre
apt-cache pkgnames
, ça risque de faire pas mal de mémoire (45237 entrée chez moi, autrement dit plus d'1Mio potentiels une fois *24. Je dis potentiels, parce qu'avec les SSO ça peut être moins, en fonction du compilo.) et de risques de throw, le tout pour faire plaisir à des gens qui n'ont rien à faire de la performance et de la portabilité, qui ne sont pas la cible première de C++?Quel réel avantage y aurait-il? Au passage,
std::basic_string<char>
oustd::basic_string<wchar>
(bon, j'ai un doute, je sais plus si c'est wchar ou wchar_t…)?Au moins n'est-il pas null, nil, nul ou whatever truc qu'on peut voir ailleurs. Ici, tu oublies un truc: en C++ on ne paye pas pour ce qu'on n'utilise pas. Et ce n'est pas toujours utile d'initialiser tes variables quand tu les déclares: par exemple une variable qui sera initialisée dans une boucle, et utilisée après la fin de cette boucle, il n'y a aucune raison de l'initialiser avant.
Au passage, ton compilo te préviendra pour 99% des cas (jusqu'à présent, il m'a toujours prévenu, mais bon, je laisse place à l'incertitude).
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 1.
La plupart des développeurs C++.
Les fichiers de la SL n'ont pas d'extensions. Pas mal de libs utilisent ".hpp". On voit régulièrement ".tpp" pour les templates. Entres autres.
Mais honnêtement, ça ne me gênerait pas outre mesure que l'on ne soit plus obligé de se taper les header guards, bien au contraire.
Hum. Goto, parce que tu le remplaces par les exceptions, c'est ça? Le support des exceptions augmente, selon un document que j'ai la flemme de rechercher, le binaire d'environ 10%. Pas forcément possible pour tout le monde. void*, ça nous permets de nous interfacer avec du C, avec des fonctions aussi «obsolètes» que dlopen.
Autant je te rejoins sur les header guards, autant pas sur les goto/void* (alors que je n'utilise pas goto et que je ne suis que client de void*).
C'est un point de vue. Pas celui de tout le monde.
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 4.
Java à interdit aux dév. de faire des fonctions. Résultat, ils font des classes statiques. Toutes les exceptions doivent être rattrapées? Ok, mais on ne fais rien.
Je parle de Java ici, mais c'est juste le 1er exemple qui me viens en tête. Quand un langage limite ses utilisateurs, ils contournent les limitations, parfois à bon escient (la classe statique, avec le main statique) parfois non (les exceptions) et dans tous les cas, je trouve que ça alourdit la lecture.
C++ n'est pas parfait niveau simplicité de lecture (surtout quand on lit du code template) mais j'apprécie qu'il ne me force pas à suivre une école de pensée unique, qui ne sera pas optimale pour certains cas particuliers.
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.
Je n'utiliserais pas la même signature moi, je ferai plutôt
static bool Derived::clone( Base const& b, Derived& a );
du coup, tu fais ce que tu veux quand ça échoue, avec a qui n'est pas modifié si tu as fais les choses bien.Personnellement, j'opte de plus en plus souvent pour l'usage de constructeurs nommés (
static foo::make( ... );
) et quand ça rate (paramètre foireux, initialisation impossible, whatever), selon mon API je throw ou retourne foo().C'est un idiome plutôt pratique, qui peut palier à ton problème (si je l'ai bien compris) et même permettre d'avoir plusieurs «constructeurs» avec les mêmes signatures, exemple (bidon) si tu veux générer un pixel RGB, tu peux avoir 3 constructeurs nommés pour faire les nuances d'une couleur unique.
En bonus, dans certains cas, ça évite de se taper les operator= & Ctors, alors que l'on veux juste ajouter un moyen de convertir un type dans un autre. En malus, je "perds" une partie des conversions automatiques (enfin, surtout parce que j'ai souvent la flemme de me tapper les operator=&Ctors).
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.
Ah bah merci, me coucherais moins bête :)
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 3.
Le truc, c'est que le C est un langage tellement simple (pas d'héritage, donc pas de méthodes virtuelles donc pas de vtable, pas de RTTI, pas d'exceptions) que c'est relativement simple d'avoir des ABI compatibles (je ne dis pas qu'elles le sont toujours) entre divers fournisseurs.
C'est d'ailleurs pour ça que tout le monde passe par le C pour discuter les uns avec les autres.
Pour les autres langages, souvent plus riches en fonctionnalités, je dirais qu'il y a 2 cas:
Si on prend un langage «propriétaire», non pas dans le sens code source fermé mais dans le sens qu'il n'existe qu'un compilo et que c'est lui la norme, le problème se résous de lui-même.
Mais dans le cas d'un langage comme C++ (doit y en avoir d'autres je pense), qui est un standard ISO pouvant être implémenté par de nombreux acteurs et sur tout type de matériels, le fait de ne pas avoir d'ABI standardisée (dans les spec. du langage) me semble être un pré-requis, pour la faisabilité (diversité des acteurs, code fermé & P.I., etc.) comme pour les possibles optimisations dépendant des architectures. Enfin, pour les optimisations, c'est ce que je me suis laissé dire: n'y connaissant pas grand chose, je ne peux juger.
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 1.
Et, dans le cas de ta critique, tu es dans la partie "souvent" ou dans l'autre? :D
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 4.
D'une part, j'ai bien précisé: "je pense", je n'ai pas dit "c'est une erreur". La nuance est faible, mais existante: je n'ai jamais prétendu être bon, donc je peux penser des conneries.
Ceci étant dit, j'ai beaucoup de mal avec l'idée qu'un objet soit possédé par plusieurs autres à la fois, en terme de maintenance j'imagine mal ça simplifier les choses.
D'ailleurs, c'est assez amusant. Je me rappelle qu'au début je trouvais l'idée super. J'ai réfléchi à l'utiliser sans jamais y trouver d'usage mais je me disais juste que l'occasion ne s'était pas présentée. De fil en aiguille j'étais tombé sur un billet de blog ou l'auteur expliquait pourquoi il estimait que l'utiliser ne lui semblait pas une bonne idée. J'ai essayé de répondre à ses points (vu que je n'étais pas d'accord du tout), et, en répondant, je me suis aperçu que tous les arguments que j'avais en faveur du shared_ptr étaient mauvais. Du coup j'ai bien du passer 2H à ne rien répondre.
Après, peut-être qu'un jour je tomberai sur un cas d'usage réel, après tout, j'ai bien eu une fois un cas ou l'héritage en diamant m'a été utile (je ne dirai pas que ce cas était super bien ficelé, mais dans la situation c'était ça ou duplication d'une quantité de code assez conséquence comparé à la taille du projet)…
Pour conclure, je veux bien un cas d'usage quotidien de shared_ptr. Si je peux être détrompé, tant mieux.
[^] # Re: Stabilité qui a pris du temps ?
Posté par freem . En réponse à la dépêche KDE Plasma 5.8 LTS. Évalué à 5.
Ah ça… les goûts et les couleurs…
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2. Dernière modification le 03 octobre 2016 à 14:15.
Non, au revoir la move semantic, et donc au revoir std::unique_ptr.
Mais std::auto_ptr (maintenant déprécié car remplacé par unique_ptr qui est plus sûr, certes) existait déjà en C++03. Et c'était toujours mieux que d'utiliser des raw, mais personne ne l'utilisait. Probablement parce que, par exemple, les gens qui enseignent ne connaissaient pas nécessairement son existance (j'en ai jamais entendu parler à l'école, des pointeurs intelligents… de manière générale, on à très peu parlé de la lib standard, je ne sais vraiment pas pourquoi, ça aurait réduit pas mal certaines conneries).
Et pour ce qui est de shared_ptr, je pense que ce truc est une erreur, mais bon, un pointeur intelligent avec compteur de référence ce n'est pas ce qu'il y a de plus difficile à coder non plus.
Enfin, tant qu'on reste dans le mono-threadé ou si l'on accepte d'utiliser des libs externes: le multi-thread était inexistant avant C++11 après tout.
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 1.
Ici, ça me semble clair: c'est B qui définit qui à le droit d'utiliser ses propriétés protégées. Le fait que D considère fr() comme une amie ne donne absolument pas le droit à fr() d'utiliser une propriété protégée de B, uniquement celles de D.
Donc pour moi, g++ à tort et clang++ raison. Et je doute que le standard ait changé sur ce point: il faudrait trouver un vieux compilo standard de l'époque pour etre sur.
Ceci dit, personne n'a dis que le C++ n'était pas trop compliqué. C'est de notoriété commune (et en plus maintenant on multiplie les façons de gérer un prototype de fonction avec le auto foo() ->type).
Une fois ajouté la dessus le fait que certains compilos vont ajouter silencieusement leurs tolérances et extensions si tu ne précises pas un standard, et tu multiplies les risques de confusion, sur un truc déjà complexe.
# Le meilleur langage est celui que tu maîtrise le mieux
Posté par freem . En réponse au message Quel langage choisir pour developper un logiciel de gestion , . Évalué à 3.
Tout est dans le titre, surtout si tu n'as que 2 ans pour refaire ton application.
Au final, ce qui importera probablement le plus, ce sera ta conception, le langage ne sert pour moi qu'a traduire.
Pour un soft de gestion, le plus gros sera fait par la BDD, et elles offrent toutes des bibliothèques utilisables dans tous les langages un minimum populaires (et pour les autres, il faut adapter la lib C, mais bon…). Tu peux aussi utiliser des technologies qui permettent de requêter n'importe quel SGBDR avec une seule lib, je ne sais plus comment elle s'appelle mais il y en a au moins une.
Bon, après, si tu es rouillé, je dirais évites le C, tu te prendra la tête pour pas grand chose (gestion des ressources (RAM, mais aussi connections à la BDD ou identifiants des fenêtres graphiques) manuelle, si tu oublies un truc tu as un crash ou pire, un bug longtemps après).
Ceci étant dit, je me pose la même question que d'autres: avant de coder, pourquoi ne pas regarder l'existant auquel tu peux avoir accès?
Je doute que tu aies des besoins transcendants après tout (si je comprend bien, tu as une petite structure) et partir d'un existant sera probablement bien plus léger en terme de charge. Sans parler du fait qu'un existant a une communauté déjà en place, tu n'aurais pas besoin de faire toute la maintenance tout seul.
Je pense notamment à dolibarr, qui a fait l'objet de plusieurs dépeches ici, mais il y en a probablement d'autres.
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.
Ok. Faudra que j'y jette un oeil.
Dis-moi, tu as remarqué que j'ai parlé de C++ standard, et donc de 98?
As-tu aussi remarqué que je parlais de prendre un code source du vieux standard et de le compiler avec un compilateur moderne?
Si tu réponds oui, alors donne moi un bout de code répondant au 1er standard C++, c'est à dire de 1998 (donc, non, pas de 1995…) que je ne puisse pas compiler avec, par exemple, clang3.8.
Quant au C++17, vu qu'il n'est pas encore sorti, ça va être difficile de tester.
Tout à fait. Mais pour moderniser, il faut encore être capable de compiler l'original.
Imaginons un peu, tu tombes un jour sur un logiciel open source sympa mais plus maintenu depuis 10-15 ans (allez, genre, autorealm. J'aimerai vraiment arriver à le recompiler lui… mais c'est du delphi, et je me sens pas motivé pour acheter une licence windows + whatever compilo juste pour moderniser et porter ce logiciel sous linux).
Le fait de pouvoir le compiler malgré l'absence de mise à la modernité pendant plus d'une décenie est un peu vital pour pouvoir le moderniser ensuite sans reprendre tout le code source.
C'est une des choses que je pense que C++ permets.
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.
Je comprend.
Sauf que ce bout de code:
C'est du C++ parfaitement valide. L'ABI est stable, bien que j'aie un doute sur le fait que ce soit par convention ou par standard.
Le fait est que, bien sûr, il faut se débarasser de la totalité des fonctionnalités C++ dans l'API, mais bon… je pinaille, j'avoue :)
En tout cas, j'en retire que ce que tu fais avec python+rust, tu peux le faire avec python+C++.
Je ne suis pas expert, mais j'ai l'impression que c'est un peu la meme chose partout, de ce point de vue la. Enfin, non, puisqu'en C++, justement, il n'y a pas besoin d'autant de colle.
Objectivement, je dirais avantage à C++ en terme de quantité de code vital pour importer du code C, et pour cause, un sous-ensemble du C++ est entièrement compatible avec le C (mais pas l'inverse, parce qu'il me semble que le C++ réserve certains mots non réservés par le C, genre
public
).Enfin, ce genre de trucs me rappelle la fois ou j'avais du interfacer du C++ avec powerbuilder12… j'avais fini par pondre un wrapper complet, qui permettait avec quelques macros (non nécessaires elles, mais ça réduisait méchamment le boilerplate) et beaucoup de template, histoire d'etre sur que quand ça plantait ça venait pas de la colle powerbuilder/C++… foutu langage proprio de merde, si tu veux mon avis.
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 7.
Existe-t-il un langage qui empêche complètement les erreurs catastrophiques? Qui n'expose jamais au risque de perdre des données, qui génère des programmes dont on est sûrs à 100% qu'ils ne planteront jamais?
A priori, ADA pourrait coller à la description, mais, je ne l'ai pas vu cité encore. J'ai vu cités Swift, Go, et d'autres dont je n'ai jamais entendu parler. Ceux-la, ils y collent à la description? Et en pratique, ça donne quoi?
Faut dire que, quand on voit le code le STL de g++, on comprend que ce soit long à compiler… ça s'include dans tous les sens, avec des macros en veux-tu en voila, des héritages et aggrégations tortueux… et de manière générale un code illisible (chose amusante: ils indentent parfois avec des espaces, parfois avec des tabulations. Je ne parle pas d'aligner le code, mais bien de l'indentation!).
Je n'ai pas fait de comparaisons sur les temps de compilations, mais depuis quelques temps j'utilise libc++ de llvm. Rien que pour comprendre pourquoi un truc merde, c'est 10 fois plus simple (même si je reste gêné par le fait qu'il soit impossible d'interdire au compilo les inline quand on debug…).
Au final, j'utilise clang parce que plus rapide et plus clair que gcc depuis plusieurs années, et cette année j'ai commencé à utiliser leur STL.
Plus ça va, moins j'utilise d'outils GNU pour le dev, et mieux je me porte. Ca ne m'empêche par de reconnaître que je leur dois une fière chandelle, hein, mais je pense que certains défauts repprochés au langage C++ sont plus dus aux outils libres «standards de facto» qu'au langage lui-même. Ou du moins, que ces fameux outils sont une cause aggravante. Le poids de l'historique, sûrement.
Ah oui, j'oubliai: j'essaie aussi de tendre vers l'utilisation de musl, histoire qu'on me dise pas que j'ai oublié la libc :) (mais bon, oui, il me reste pas mal de trucs à remplacer, faut du temps, surtout que je fais ça pour le fun surtout).
Existe-t-il un autre langage natif ayant un mécanisme de templates aussi puissant que celui du C++, et qui offre les mêmes perfs (à peu près, du moins)?
Rust, peut-être? (vraie question)
Malheureusement, on en a besoin pour pouvoir utiliser des trucs codés en C. Dans certains cas, ça permets aussi de réduire le code boiler-plate.
Mais, c'est vrai: ce truc est un générateur de galères, quand il est utilisé abusivement. Les fonction inlinées sont par exemple bien plus intéressantes que les macros (surtout en combinaison avec les template), et pourtant dans certains bouts de code on voit encore des macros.
La dernière fois que j'ai vu des macros utilisées, c'était soit dans du code C, soit dans des framework de test, cela dit.
Reste donc que l'usage d'import de header, et je suis d'accord pour dire que ça serait pas mal qu'il saute.
Tu peux. Il suffit qu'elle soit déjà définie quand elle est utilisée. Ca m'arrive de faire des petites structures templates internes à un fichier, que je n'expose pas publiquement ça aucun intérêt.
Je me doute que tu le sais, mais ce n'est pas nécessairement le cas de tous, je me permets donc cette clarification :)
Vrai. C'est lent.
Je me demande quelle est la part de responsabilité liée à l'ISO, ceci dit. La plupart des langages qui sortent, au final, n'ont qu'une implémentation de référence, pas de normalisation réelle.
Hors, cette standardisation officielle et internationale est une force de C++ pour moi.
Du coup, je comparerai la lenteur d'évolution de C++ à Debian: c'est lent et vieux, c'est vrai, mais le fait que ça n'aille pas trop vite semble avoir pour conséquence que la maintenance est plus simple pour les utilisateurs (un vieux code C++ compile sur un compilo moderne sans trop de soucis, et une Debian peut être up/down gradée de la même manière). Pas la création d'un système fonctionnel, sa maintenance, j'insiste.
Marrant, c'est justement pour la gestion de la mémoire que j'apprécie le C++. Parce qu'en C++, si je veux utiliser un GC, je peux. Si je veux utiliser des pointeurs intelligents, je peux. Si je veux utiliser des pointeurs nus, je peux encore!
J'ai le choix, bon sang, et c'est bien d'avoir le choix, de la meme manière que c'est bien de pouvoir choisir entre windows, mac OS, Debian, voidlinux, FreeBSD, OpenBSD, etc.
C'est perfectible, bien sûr, mais quand je lis qu'il est obligatoire d'utiliser des pointeurs nus en C++, je comprend que l'auteur de la phrase lue ne connaît pas le C++ (je ne dis pas l'avoir lue ici, mais j'ai déjà lu ça, plus d'une fois).
Sincèrement, avec la STL, les références et les itérateurs, les pointeurs nu ne sont simplement qu'une façon de s'interfacer avec le C ou les vieilles bibliothèques. Rien de plus.
A noter un repproche que je fais aux pointeurs intelligents standard: ils ne savent gérer que la mémoire, alors que ce n'est qu'une seule des ressources que l'on peut manipuler (alors qu'un descripteur de fichier UNIX est un int, par exemple). Sans parler du fait qu'ils aient un overhead pour moi inutile (évident pour shared_ptr, moins pour unique_ptr, mais le fait est qu'un pointeur pour stocker l'@ du destructeur est maintenu et testé, alors que ça aurait pu être passé en template. Mais j'imagine que certains ont l'usage de modifier le destructeur au runtime?).
Maintenant, oui, je l'admets: utiliser des références ou des itérateurs ne protège pas contre les segfaults, et il n'y a rien à ma connaissance en C++ pour gérer ça. C'est un des points qui font que je veux me mettre à Rust, un jour.
Le C++ ne permets pas non plus, à ma connaissance, de vérification sur les under/over-flow d'entier. C'est un problème, pour moi, vraiment. D'un autre côté, ça permets un code plus léger et plus rapide, parce que si à chaque addition on devait faire une vérification à l'exécution, c'est du code en plus à exécuter, de la lenteur.
Ce que j'apprécierai vraiment, ça serait de pouvoir faire ça, uniquement pendant le debug.
Et ça n'arrivera jamais, j'espère. Si une telle fonction devait exister, elle aurait plutôt sa place dans les algorithmes, autrement dit, ce serait
std::delete_at( iterator it, container& cont );
ou un truc de goût là.Les APIs de la STL sont déjà assez moyennes comme ça, à mon avis (à la fois trop riches et pas assez: trop riches parce que, par exemple, std::vector::insert pourrait être implémenté en dehors du conteneur (avec une combinaison de std::move&std::inserter par exemple) alors qu'il est difficile de connaitre le cout mémoire réel d'un conteneur (pour vector c'est faisable, mais pour std::map?) ).
En tout cas, c'est marrant, dans la liste des défauts de la STL, j'aurai pensé voir std::string au moins une fois (parce qu'elle s'interface relativement mal avec le reste de la lib standard, et que pour une gestion de chaine de caractères, ça ne permets meme pas de diviser facilement… bref je la trouve bancale.).
Comme tout les langages sauf le C, en fait. Je pense que l'on devrait arrêter de ce soucier du C, franchement.
Je pense qu'une bonne part des emmerdes du C++ viennent du C.
Personnellement, si j'apprécie énormément le C++, c'est parce que c'est un langage qui donne le choix.
Il me donne le choix d'utiliser les template.
Il me donne le choix d'utiliser le modèle mémoire que je veux (GC, pointeurs intelligents, pointeurs nu. Bon, ok, pour le GC il n'y a rien dans la lib standard, probablement parce que la culture C++ préfère la RAII).
Il me donne le choix d'utiliser la RTTI (j'inclue dedans les méthodes virtuelles).
Il me donne le choix de faire de l'héritage multiple et même en diamant (ça m'est déjà arrivé une fois de m'en servir).
Il me donne le choix d'utiliser les exceptions (à condition de se passer de la STL, certes).
Rien n'est obligatoire, il faut choisir ce que l'on utilise. Pour certains, c'est un défaut. Pour moi, c'est une force.
Pour refaire le parallèle avec les distributions Linux: pour moi, l'apparition de Devuan, d'Ubuntu, d'Archlinux, et j'en oublie, ce sont de bonnes choses, parce que ça donne le choix.
Alors bien sûr, avoir le choix implique de prendre des décisions, mais pour moi c'est un peu le coeur de métier d'un développeur, de prendre des décisions.
Mais ce n'est pas parce que j'aime beaucoup C++ que je dis qu'il n'a aucun défaut. Seulement, à l'heure actuelle, je ne vois que Rust pour le remplacer, et il est encore jeune, on n'a pas encore eu le temps de voir comment il vieillit.
Avant de dire que Rust peut remplacer C++, il faudra au moins 5 ans d'écart entre la sortie de sa 1ère version stable et l'heure du jugement, justement pour avoir du recul.
On n'a aucun recul sur Rust, contrairement à C++ ou l'on parle de près de 20 ans ( ~18 de standard ISO).
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 3.
Je ne le nie pas, les temps de compilation C++ peuvent être longs. Ceci étant dit, quelle est la part de lenteur due au langage, et quelle est la part due aux outils, make, par exemple?
Parce que selon certains, pour une compilation incrémentale, make est inutilement très lent.
Et aussi, je pense que comparer uniquement les temps de compilation est une erreur de nos jours. Après tout, si on prend Java ou C#, il me semble bien qu'une partie de la compilation est faite au lancement de l'exécutable.
Du coup, ce qui serait objectif, c'est de comparer compilation + temps de première exécution, non?
[^] # Re: Donc pour résumer…
Posté par freem . En réponse à la dépêche C++17, Genèse d’une version mineure. Évalué à 2.
Intéressant.
Donc ce n'est pas un problème si C++ ne gère pas les GUI, puisqu'on peut aussi interfacer avec du "Java/Kotlin/C#" (même s'il faut passer par du C++ Céifié à cause de l'ABI, mais c'est un autre sujet que l'absence de GUI, et j'ai beau aimer le C++ je sais que le manque d'ABI stable est un véritable problème. Enfin, je ne sais pas comment ça se fait en Rust, non plus).