IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Mamadou Babaei : « C++ n’a pas besoin d’une nounou comme le vérificateur d'emprunts de Rust »


Sujet :

C++

  1. #21
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    769
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 769
    Par défaut
    Citation Envoyé par djm44 Voir le message
    Ce qui étonne aussi c'est que les reproches s'adressent au C++ et au C. Par contre Java, Python, Javascript, Pascal , Fortran , Basic ... là la mémoire et le reste c'est nickel
    En fait cela part d'un constat assez simple: ~70% des CVE sont liées à des erreurs mémoire (buffer overflow, use after free, etc) et concernent principalement C et C++. Pour ne rien arranger, ce sont aussi les plus critiques. Les autres langages cités n'ont pas ce problème puisqu'ils font systématiquement une vérification des bornes pour lancer une exception et utilisent un GC. En gros, on perd en contrôle ce qu'on gagne en sécurité.

    Je conseille la lecture de ce papier: Secure by Design: Google's Perspective on Memory Safety.

    Du coup, pourquoi un focus sur Rust ? Parce qu'il se veut sécurisé par design sans compromit sur les performances. Par conséquent, il joue dans la même cour que C ou C++. Quand on reste dans le monde safe de Rust, le langage et la bibliothèque standard ont de forte garanties sur les bugs mémoire. Quand on a besoin de chose spécifique, on peut utiliser des blocs unsafe. En prenant les catégories listées dans le papier:

    - Spatial Safety bugs (e.g. “buffer overflow”, “out of bounds access”): via les fonctions qui retournent un Option plutôt qu'une valeur hors borne (le pattern matching et la destructuration aident aussi à ne pas lire la valeur dans l’Option sans vérifier qu'il est valide). Si on ne veut pas de vérification sur les accès (et donc pas d'Option), on passe en unsafe (gros warning) ou on utilise des itérateurs (le système d'emprunt garantissant qu'il reste valide, par exemple, impossible d’agrandir un Vec si on itère dessus, car cela pourrait invalider l'itérateur).
    - Temporal Safety: vérifier par le compilateur.
    - Type Safety: on est dans du unsafe.
    - Initialization Safety: le langage permet de déclarer des variables sans les initialiser, mais toutes les branches qui la lisent doivent l'initialiser (vérifier par le compilateur). Pour des workflow complexe, on est dans du unsafe.
    - Data-Race Safety: en grande partie vérifié par le compilateur via les traits Send et Sync et comment sont construit les primitives de synchro (valeur à l'intérieur de l'objet de synchronisation plutôt qu'a côté).

    Alors qu'en C ou C++ il n'y a aucune de ces garanties, que se soit côté compilateur ou la bibliothèque standard, on est tout le temps en mode "unsafe". Même les retours via Option que pourrait adopter la bibliothèque standard sur les accès serait une vaste blague en C++: trop de limitation et de facilité à lire sans vérification en absence de pattern matching (je crois que les propositions se battent toujours sur la syntaxe).

    Citation Envoyé par foetus Voir le message
    Et il y a aussi la gestion des dépendances, et notamment les modules C++ qui ont mis 23 ans à arriver (depuis la norme 2003 et le fameux export) ... et c'est encore du "bas niveau" avec 1 normalisation du format de précompilation (<- si j'ai bien tout compris)
    Tu es sûr pour export de C++03 ? J'ai l'impression que c'était surtout une facilité pour réduire les temps de compilation des templates. Mais avec plein de contrainte. Éjecté en C++11. Après il y a eu des expérimentations par Google sur des modules, un grand vide, puis finalement des propositions pour avoir quelque chose en C++20 que les compilateurs commencent à peine à bien supporter.

    Par contre, je n'ai pas souvenir d'une normalisation du format. Pour moi, ce n'était pas voulu, chaque compilateur étant libre de faire comme il veut. Mais j'ai vu passé des trucs sans lire, probablement concernant le mapping source <-> pré-compilé (ça semble assez galère de gérer les dépendances à la main, clang fournit des outils spécifiques pour ça).

    Citation Envoyé par foetus Voir le message
    Pendant ce temps les autres langages travaillent : [...] la facilité (les bibliothèques standards qui intègrent tellement de trucs, contrairement à la std qui n'a toujours pas de threads (que bas niveau), 18 ans pour avoir les tableaux associatifs et la gestion de l'unicode ), ...
    Personnellement, je suis plutôt contre avoir une bibliothèque standard intégrant plein de truc. Plus il y a de domaine couvert par une SL, plus il y a besoin d'expertise. Faire quelque chose qui fonctionne est "facile", mais faire quelque d'efficace l'est beaucoup moins. Je vais prendre les regexes comme exemple.

    - Il faut choisir une syntaxe ou un standard. Il y en a 2 assez connu: PCRE et POSIX. À cela s'ajoute toutes les variantes. À partir du moment une syntaxe existe, elle ne peut presque plus évoluer puisque le pattern aurait un comportement différent. Par conséquent, on se trouve lié à la version d'un standard -> évolution lente, problème avec des lib header only.
    - Il faut aussi définir quel est le cadre d'utilisation, ce qui va beaucoup influencer l'implémentation (et l'interface). Par exemple, préfère-t-on une recherche en temps constant avec une mémoire stable, quitte à ce qu'elle ne soit pas la plus rapide ou une implémentation le plus rapide possible avec des corners cases ? Pour info, un mauvais pattern avec PCRE peut prendre plusieurs secondes sur un texte d'une centaine de caractères.
    - Il faut des personnes compétentes sur le sujet. On peut faire une implémentation triviale, c'est ce qu'à fait libstdc++. Résultat, a* sur quelques milliers de 'a' fait un dépassement de pile.
    - Maintenant qu'on a une implémentation, il faut une stabilité de l'ABI (parce que C++...) -> gros frein sur les modifications.

    Peaufiner un moteur regex demande beaucoup d'effort, il suffit de voir les gros existant pour s'en convaincre (PCRE2, RE2, hyperscan / vectorscan). Mais c'est pareil pour les parseurs json (nlohmann::json, glaze, daw_json_link, simdjson, etc) et ainsi de suite. Chacun vient avec ses forces et faiblesses, mais en mettant dans le standard, on se retrouve avec quelque chose qui évolue beaucoup plus lentement, beaucoup moins facilement et avec très peu de spécialiste travaillant dessus (voir pas du tout).

    En plus, comme cela se voudra à usage général, on se retrouve vite avec quelques choses qui pourrait être beaucoup plus efficace en changeant de lib. Mais si c'est dans le standard, la plupart des dév feront un choix par commodité. À contrario, avec un gestionnaire de lib qui se tient, on peut facilement prendre n'importe quoi par commodité (pas spécialement plus d'effort), mais les mainteneurs de compilateur et le standard ont beaucoup moins de charge de travail.

  2. #22
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2019
    Messages
    319
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2019
    Messages : 319
    Par défaut
    Citation Envoyé par foetus Voir le message
    C'est pourtant assez clair : les normes depuis C++11 apportent de nouvelles sécurités (comme les pointeurs intelligents, les vues, les déplacements, ...) mais tout cela reste
    • à maîtriser - donc bien lire les normes. Par exemple, les constructeurs il y a 3 façons (parenthèse, sans parenthèses et accolades). Ou alors lors des fermetures, déplacement ou pas ? la syntaxe n'est pas facile.
    • que du "bas niveau" - donc avoir 1 profil très expérimenté
    Et oui, ça s'appelle être un professionnel, savoir utiliser son outil de travail. Incroyable, non ?

    Comme un électricien doit savoir câbler correctement et respecter les normes, le maçon doit savoir faire un mélange correct pour son béton sinon l'immeuble s'effondre, l'ingénieur en travaux public doit savoir respecter à la lettre les normes de mise en place d'un assainissement et autres, etc.

  3. #23
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 806
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 806
    Par défaut
    Citation Envoyé par d_d_v Voir le message
    Et oui, ça s'appelle être un professionnel, savoir utiliser son outil de travail. Incroyable, non ?
    Mais tu as plusieurs types d'outils professionnels pour sécuriser son code
    • le C++ avec ses pointeurs intelligents, ses vues ... CRT, RAII, ..
    • le Rust avec son compilateur, borrow checker, ...
    • Java et C# qui utilise 1 machine virtuelle/ ramasse miettes


    Et depuis 5-6 ans on reproche au C++ de demander des profils rares (> 8 ans d'expérience, 1 truc comme cela), d'avoir des temps de développement assez longs ... et la liste des bugs mémoire toujours aussi importante.
    Les normes depuis C++11 n'ont rien amélioré (que ce soit sur la sécurité du code que sur la gestion des dépendances ou sur la facilité de développer/ debugger).

    Je sais que lorsqu'on maîtrise le C++ on se sent "supérieur", meilleur ... le C++ devient 1 b*rdel

    Et depuis 5-6 ans pleins de sociétés (même le noyau Linux et FFmpeg) se forment sur Rust et cela semble faire son petit bonhomme de chemin ... le seul truc qui reste au C++ c'est sa vitesse d'exécution et sa énorme base de codes
    D'ailleurs ce n'est pas pour rien que depuis 2022-2023, le comité C++ réfléchit à intégrer le borrow checker (il me semble que le comité C++ avait annoncé 1 grande surprise en 2022-2023)

    Donc voila il y a 2 types de professionnels : ceux qui font du C++ et les autres

  4. #24
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 498
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 498
    Billets dans le blog
    1
    Par défaut
    Comme un électricien doit savoir câbler correctement et respecter les normes
    J'ai rénové mon nouvel appartement en 2023. L'immeuble avait 50 ans.

    J'ai changé toutes les prises et tous les interrupteurs. Pourquoi ? Pour en avoir des éléments modernes plus sécurisés. Par exemple, les interrupteurs modernes ne permettent pas de prendre une tige de fer, de l'enfoncer dans un des trous, et de mourrir. Il faut prendre 2 tiges et enfoncer dans les 2 trous en même temps pour désenclencher la sécurité. Autre exemple : quand tu "ouvres" une prise ou un interrupteur moderne, il n'y a pas de pièce nue sous tension et donc tu ne peux pas mourrir juste en touchant un truc.

    J'ai rajouté aussi la terre sur certaines prises (malheureusement pas sur toutes) car il y a 50 ans, on ne cablait pas la terre.

    Les normes et les façons de faire évoluent. Ce qui était OK il y a quelques années peut ne plus l'être aujourd'hui. A un instant T, on fait du mieux qu'on peut. Si à l'instant T+1, on trouve encore mieux, pourquoi ne pas faire encore mieux ?

    Et oui, ça s'appelle être un professionnel, savoir utiliser son outil de travail
    C'est aussi choisir son outil de travail.

    Notre métier développeur.se n'est pas de connaitre par coeur toutes les subtilités du C++. C'est de produire des logiciels de qualité au meilleur coût. Connaitre par coeur les subtilités du C++ est une nécessité quand nous utilisons C++ pour réaliser ces logiciels.

    Nos façons de coder en C++ ont évolué avec les années parce que le langage a évolué. Personne aujourd'hui ne défendrait sérieusement l'usage de pointeurs nus sous prétexte que "les vrai.e dev savent gérer la mémoire manuellement". On fait du RAII et on utilise les pointeurs intelligents de la std.

    Après de nombreuses années de C++, je fais du Rust depuis quelques mois. Je pense qu'il est encore un peu tôt pour dire que Rust doit remplacer C++. Mais je trouve qu'il est déjà bien assez tard pour ne pas essayer sérieusement ce langage. Ne serait-ce que pour se rendre compte de certains manques du C++ et se demander comment on pourrait l'améliorer.

  5. #25
    Membre actif

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2023
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2023
    Messages : 75
    Par défaut
    Les jeunes développeurs, formés dans un univers DevOps/API-first, privilégient souvent les langages sûrs par défaut, comme Rust, Go ou Python. Les vétérans du C++ ...
    Je note ce passage de l'article qui est assez surprenant en faisant de Python un langage sur alors qu'il a été écrit en C. Il suffit de parler d'un langage à la mode pour que soudain il devient sur quand bien même ses racines ont été conçues en C voir C++ . Cette sévérité sélective à l'égard du C et C++ sur cette obsession de la gestion mémoire me parait excessive.

  6. #26
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 569
    Par défaut
    @djm44, dis-moi, le premier compilateur C, il a été écrit en quoi ?

  7. #27
    Membre confirmé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2021
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2021
    Messages : 114
    Par défaut
    Citation Envoyé par djm44 Voir le message
    Je note ce passage de l'article qui est assez surprenant en faisant de Python un langage sur alors qu'il a été écrit en C. Il suffit de parler d'un langage à la mode pour que soudain il devient sur quand bien même ses racines ont été conçues en C voir C++ .
    Mauvaise interprétation. Vous voyez bien qu'une bonne part des intervenants connaissent à la fois le C, le C++ et Rust.
    Quand on peut comparer ces langages, on peut en souligner les qualités et les défauts. Et C++ ne s'est pas améliorer autant qu'il aurait été souhaitable.

    Citation Envoyé par djm44 Voir le message
    Cette sévérité sélective à l'égard du C et C++ sur cette obsession de la gestion mémoire me parait excessive.
    C'est un point important, mais pas seulement. Ce qui fait la qualité de Rust, c'est vraiment un ensemble de capacités modernes qui se marient très bien.
    Et ça avance. Par exemple, il est facile de faire de la programmation asynchrone non-bloquante en Rust (c'est à dire de l'async en Rust, ce qui correspond + ou - aux co-routines en C++) -> le runtime tokio sur crates.io est quasi-standard.

    Exemples: multithread (playground) versus asynchrone non bloquant (playground -> utiliser l'option Run), où on voit une certaine cohérence des deux paradigmes.

    Le faire en C++, je n'ose même pas. Ce n'est pas une sévérité sélective, on compare des langages qui concernent potentiellement des applications similaires et on peut regretter certaines perspectives du C++.

  8. #28
    Membre averti
    Homme Profil pro
    Directeur Recherche et développement
    Inscrit en
    Janvier 2012
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Directeur Recherche et développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2012
    Messages : 59
    Par défaut Rust ou C++? Définitivement le C++.
    Pourquoi cherche-t-on la facilité? Y-a-t-il "une peur" de devenir un expert en programmation? J'ai 35 ans d'expertise en C++ hautement optimisé et mon constat est le suivant. Un débutant qui cherche la facilité passe forcément à côté des subtilités de la programmation et son expertise ne se développe pas. Ceci est une grave lacune pour un professionnel qui doit viser les hauts standards de qualité. Je suis d'accord avec Mamadou mais pour d'autres raisons. Personnellement, autour des années 2000, je me suis mis véritablement au C++. À l'époque le C++ était plus simple que le Rust présentement, mais aussi beaucoup hasardeux (Pas de libraire standard). Fuite de mémoire et autres problèmes étaient la norme dans mon code. L'utilisation du logiciel "BoundChecker" m'a permis de trouver mes erreurs comme Mamadou le propose. Il a eu des effets de bord important sur mon expertise. Premièrement, la très grande majorité des erreurs m'ont indiqué ce que je faisais d'incorrect. Un coup les erreurs identifiés et comprises, je les répétais plus dans l'avenir (sinon on est un programmeur idiot!). Deuxièmement, les quelques erreurs qui sont survenues après cela ont été causées par des mauvaises pratiques de design logiciel et de meilleures pratiques ont été adoptées. La conséquence est que depuis 15 ans, je n'ai plus de problèmes dans ce type dans mon code et dans celui que je dirige (Note: Merci à la librairie standard!)

    Je vois donc des inconvénients majeurs à passer à Rust:
    1. Dans mon cas, le Rust ne m'apporte rien de plus que ce que j'ai déjà (Mes programmes sont sécuritaires!).
    2. Le langage Rust a une certaine complexité aussi et il évolue rapidement. Ceci complique l'apprentissage des débutants.
    3. En C++ moderne, il n'y a techniquement plus de problème. L'époque du C (Malheureusement, toujours intégré et compatible au C++) est révolu et nous devrions plus enseigner le C++ en utilisant le paradigme de la programmation C.
    4. Je ne suis pas convaincu qu'en poussant la performance à outrance, nous somme capable d'approcher en Rust, les optimisations du C++. L'introduction du mode "unsafe" en Rust est pour moi un aveu d'échec à le faire (tout au moins c'est une faille énorme dans leur sacro saint principe de sécurité). Pour moi, un langage "safe" ne peut pas avoir de mode "unsafe". Si cela existe, tout le langage est "unsafe" contrairement au prétention de Rust.
    5. Enfin le point le plus important pour moi, le design logiciel en C++ est nettement supérieur. La richesse du C++ m'a permis d'utiliser d'utiliser à maintes reprises des agencements qui étaient non documentés et qui à première vue semblait illégal (Merci à Alexandrescu pour son audace et de m'avoir permis de penser autrement). Le langage nounou et strict ne permet pas ce type d'acrobatie. Mon meilleur coup dans un section critique en C++ était une amélioration de plus de 20% en vitesse et près de 10% en mémoire par rapport à un code qui suivait une avenue plus traditionnelle (Un autre programmeur m'a dit que l'on ne pouvait pas faire mieux!)

    Pour toute ces raisons, je ne passerai jamais au Rust!

    Il y a un inconvénient au C++ que je vie en tant que directeur. L'introduction d'un nouveau membre à l'équipe de programmation exige un formation intense sur notre façon de travailler, concevoir et coder. Cette formation est ardue, spécialement pour un débutant, mais croyez-moi mon expérience, ce temps est un investissement pour lui et la compagnie car les bénéfices à long terme sont immenses.

  9. #29
    Membre actif

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2023
    Messages
    75
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2023
    Messages : 75
    Par défaut
    Citation Envoyé par bacelar Voir le message
    @djm44, dis-moi, le premier compilateur C, il a été écrit en quoi ?
    En assembleur ou en B selon OS , pourquoi cette question ? Je remarque que Python dont l'API est écrite en C est considéré comme fiable mais pas le C qui l'a conçu.

  10. #30
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 515
    Par défaut
    Citation Envoyé par ChristianRoberge Voir le message
    Pourquoi cherche-t-on la facilité? Y-a-t-il "une peur" de devenir un expert en programmation? J'ai 35 ans d'expertise en C++ hautement optimisé et mon constat est le suivant. Un débutant qui cherche la facilité passe forcément à côté des subtilités de la programmation et son expertise ne se développe pas. Ceci est une grave lacune pour un professionnel qui doit viser les hauts standards de qualité.
    De quelle "facilité" te plains-tu dans le cas de Rust ? Le typage sur les durées de vie ? En quoi cela empêcherait-il de devenir un expert en programmation ? C'est un peu comme si un développeur JavaScript qui a appris à déboguer des erreurs de typage trouvait que les langages statiquement typés dont C++ étaient "faciles" car empêchaient certaines erreurs directement à la compilation et s'inquiéterait de l'impact du typage statique sur la montée en compétence des développeurs.

    Citation Envoyé par ChristianRoberge Voir le message
    5. Enfin le point le plus important pour moi, le design logiciel en C++ est nettement supérieur. La richesse du C++ m'a permis d'utiliser d'utiliser à maintes reprises des agencements qui étaient non documentés et qui à première vue semblait illégal (Merci à Alexandrescu pour son audace et de m'avoir permis de penser autrement). Le langage nounou et strict ne permet pas ce type d'acrobatie. Mon meilleur coup dans un section critique en C++ était une amélioration de plus de 20% en vitesse et près de 10% en mémoire par rapport à un code qui suivait une avenue plus traditionnelle (Un autre programmeur m'a dit que l'on ne pouvait pas faire mieux!)
    Peux-tu donner plus de détails ?

    Citation Envoyé par OuftiBoy Voir le message
    Si je commet une erreur dans mon raisonnement, je suis tout à fait capable d'entendre les arguments contre "ma petit réfexion".
    (NdlM : message déplacé dans un fil distinct)
    Hélas, je ne comprends pas comment tu as interprété les règles du borrow checker en Rust. Peux-tu donner des exemples sur les points que tu critiques ?

  11. #31
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 569
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    En assembleur ou en B selon OS , pourquoi cette question ?
    Pourquoi ne pas affubler le C des tares de ces langages, comme tu le fais pour le python et le C ?

  12. #32
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    769
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 769
    Par défaut
    Citation Envoyé par djm44 Voir le message
    Je note ce passage de l'article qui est assez surprenant en faisant de Python un langage sûr alors qu'il a été écrit en C.
    Oui et non, CPython est en C, mais ce n'est pas le seul interpréteur python existant. Il en existe en Rust, en Java, etc, même en Python (pypy) !

    Mais il faut différencier l’implémentation du langage. Le langage se veut safe de par sa spécification, ce qui ne veut pas dire que le compilateur / interpréteur n'a pas de bug. Par contre, si on a 10 millions de lignes python (des applis quelconques) + 100k de C (le compilateur), on peut considérer qu'on a 1% de code unsafe. Si tout est en C, on est à 100% de code unsafe. Quel est le mieux ?

    C'est pour ça qu'on parle de langage safe, même si la seule implémentation repose sur un langage dit unsafe: quantitativement, cette partie est ridicule. De plus, un bug dans le compilateur n'est pas à proprement parler celui du développeur python, c'est un composant externe qui peut être mis à jour sans intervention sur le code d'origine.


    Citation Envoyé par ChristianRoberge Voir le message
    Pourquoi cherche-t-on la facilité? Y a-t-il "une peur" de devenir un expert en programmation? J'ai 35 ans d'expertise en C++
    Pourquoi faire du C++ plutôt que du C ou de l'assembleur, tu cherches la facilité ? Je pense que quelle que soit la réponse, on peut aussi l'appliquer à l'utilisation de Rust.

    Citation Envoyé par ChristianRoberge Voir le message
    Fuite de mémoire et autres problèmes étaient la norme dans mon code. L'utilisation du logiciel "BoundChecker" m'a permis de trouver mes erreurs comme Mamadou le propose. Il a eu des effets de bord important sur mon expertise. Premièrement, la très grande majorité des erreurs m'ont indiqué ce que je faisais d'incorrect. Un coup les erreurs identifiées et comprises, je les répétais plus dans l'avenir (sinon on est un programmeur idiot!).
    Je vais reprendre ce que j'ai dit dans mon premier message: quelle différence entre avoir cette vérification directement au sein du compilateur qui en plus l’expliquer et avoir un outil externe qui ne détecte les problèmes que lorsqu'on passe dans la partie qui en a (comprendre: ignore les parties problématiques si notre test ne passe pas dessus). ? Le compilateur donne une erreur (avec beaucoup plus de contexte qu'un outil externe) et à force, on ne les répète plus: on apprend.

    Citation Envoyé par ChristianRoberge Voir le message
    Deuxièmement, les quelques erreurs qui sont survenues après cela ont été causées par des mauvaises pratiques de design logiciel et de meilleures pratiques ont été adoptées.
    Ne faudrait-il pas mieux que le langage empêche simplement les mauvaises pratiques ?

    Citation Envoyé par ChristianRoberge Voir le message
    La conséquence est que depuis 15 ans, je n'ai plus de problèmes dans ce type dans mon code et dans celui que je dirige (Note: Merci à la librairie standard!)
    Je suis très dubitatif quand je lis qu'il n'y a pas de problème. Je veux bien croire que de tel outils détectent beaucoup de problème (de ce que je lis, BoundChecker et l'équivalent de address sanitizer qu'on trouve maintenant directement dans les compilateurs), mais ce genre d'outil à des limites: ils ne peuvent pas détecter tous les problèmes ni tous les buffers overflow (ça ne détecte pas un overflow entr N et M pour un vector de taille N avec une capacité M). Ce n'est pas pour rien que LLVM a introduit l'année dernière l'hardening modes dans libc++ (Clang), que Microsoft fait pareil (STL hardening) et que la dernière version de libstdc++ (Gcc) active ce mode si aucune option d'optimisation n'est utilisé (il existe aussi un mode debug, qui fait bien plus de vérification, mais casse l'ABI de la SL).

    Tout ça pour dire qu'on a beau utiliser plein de bonne pratique ou de truc moderne, ce n'est pas suffisamment, on passe toujours à côté de quelque chose parce que rien ne l'empêche.

    Concernant l'activation de l'hardening mode chez google: https://security.googleblog.com/2024...-hundreds.html
    Et l'utilisation de Rust et pratique de C++ pour Android: https://security.googleblog.com/2024...s-Android.html

    Citation Envoyé par ChristianRoberge Voir le message
    Je vois donc des inconvénients majeurs à passer à Rust: [...]
    2. Le langage Rust a une certaine complexité aussi et il évolue rapidement. Ceci complique l'apprentissage des débutants.
    3. En C++ moderne, il n'y a techniquement plus de problème. L'époque du C (Malheureusement, toujours intégré et compatible au C++) est révolu et nous devrions plus enseigner le C++ en utilisant le paradigme de la programmation C.
    4. Je ne suis pas convaincu qu'en poussant la performance à outrance, nous somme capable d'approcher en Rust, les optimisations du C++. L'introduction du mode "unsafe" en Rust est pour moi un aveu d'échec à le faire (tout au moins c'est une faille énorme dans leur sacro saint principe de sécurité). Pour moi, un langage "safe" ne peut pas avoir de mode "unsafe". Si cela existe, tout le langage est "unsafe" contrairement au prétention de Rust.
    5. Enfin le point le plus important pour moi, le design logiciel en C++ est nettement supérieur. La richesse du C++ m'a permis d'utiliser d'utiliser à maintes reprises des agencements qui étaient non documentés et qui à première vue semblait illégal (Merci à Alexandrescu pour son audace et de m'avoir permis de penser autrement). Le langage nounou et strict ne permet pas ce type d'acrobatie.
    2. Je trouve assez drôle de commencer par "pourquoi chercher la simplicité ?" pour dire qu'en fait ce n'est pas simple . Mais sinon, C++ aussi évolue, comme tous les langages. Les mises à jour de Rust sont un peu plus fréquentes, mais pas énorme non plus.
    3. Je suis d'accord qu'enseigner le C pour apprendre le C++ est la pire des mauvaises idées, mais le C++ moderne (qui a plus de 10 ans maintenant) n'est pas non plus la solution à tous les problèmes. Il intègre une meilleure vision de l'ownership via les pointeurs intelligents, mais les apports au niveau de la sécurité mémoire sont très faibles (une mémoire n'est pas un problème de sécurité).
    4. En pratique, rien ne l'empêche. Rust peut même faire théoriquement mieux puisqu'il résout le problème d'aliasing, ce qui évite des load après une écriture. Mais sinon, il y a plein de benchmark et cela se vaut. Concernant unsafe, non, ce n'est pas une faille. Le mot clef ne réduit les contraintes du langage, mais permet d'utiliser des fonctions marquées unsafe et les accès aux pointeurs. Par contre, le langage ne pouvant pas garantir l'intégrité de toutes les manipulations il est à la charge du développeur de faire en sorte de les respecter. En fait, tout ce qui est potentiellement dangereux se trouve être unsafe, c'est par conséquent un excellent marqueur d'attention pour les codes à risques (qu'on va mettre dans de jolies interfaces safe).
    5. C'est quoi un design logiciel C++ supérieur ? Et quel genre d'agencements illégaux à première vue ?

    J'ai quand même l'impression que tu n'as pas vraiment étudié Rust, ni essayer de le comprendre. Par contre, tu considères qu'un langage offrant des mécanismes de vérification supplémentaire limite forcément tout le reste. Du coup non, Rust propose plein de chose qui n'existent pas en C++ ou qui commence à peine à émerger: les traits, le pattern matching, les macros hygiéniques (pour ne citer que cela). Je vois plutôt une personne qui ne veut pas essayer de découvrir un nouveau langage parce qu'habitué à en faire un autre.


    Citation Envoyé par OuftiBoy Voir le message
    3./ Puisse qu'emprunté signifie "rendre à un moment donné" ce qui a été emprunté, il faut que le compilateur puisse obliger une fonction qu'on appel et qui a "emprunté" la "propriété" de la rende au "propriétaire d'origine". Ce qui n'est pas possible en Rust, me semble-t-il.

    (NdlM : message déplacé dans un fil distinct)
    En fait si, l’emprunt est temporaire (si la fonction ne transfère pas ailleurs). Mais un emprunt se fait sur une référence, sinon c'est un transfert. Le transfert est l'équivalent d'une copie de la mémoire suivit d'un drop de la valeur précédente. Dans l'exemple que tu ne donnes de ton langage, il n'y a pas d'emprunt, seulement des transferts.

    Un emprunt ressemble plutôt à ça:

    Code rust : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    fn foo(s: &String) { } // ne fait rien
     
    fn main() {
        let mut s = String::new();
        foo(&s);
        s.push_str("abc"); // on peut toujours modifier 's'
    }

    C'est aussi le cas sur l'utilisation des variables:

    Code rust : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    fn main() {
        let mut a = String::new();
        // let b = a; // transfert
        a.push_str("abc"); // serait impossible si on décommente la ligne au-dessus
        {
            let b = &a;
            //a.push_str("abc"); // partage avec b, modification interdite
            println!("{}", b);
        }
        a.push_str("abc"); // ok, plus de partage, b est détruit
     
        let b = &a;
        //a.push_str("abc"); // partage avec b, modification interdite
        println!("{}", b);
        a.push_str("abc"); // ok, le partage s'arrête à la dernière utilisation de b
    }

  13. #33
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 308
    Par défaut
    Citation Envoyé par ChristianRoberge Voir le message
    a- Personnellement, autour des années 2000, [...] À l'époque le C++ était [...] mais aussi beaucoup hasardeux (Pas de libraire standard). Fuite de mémoire et autres problèmes étaient la norme dans mon code.

    [...]
    3. En C++ moderne, il n'y a techniquement plus de problème. L'époque du C (Malheureusement, toujours intégré et compatible au C++) est révolu et nous devrions plus enseigner le C++ en utilisant le paradigme de la programmation C.

    [...]
    c- Il y a un inconvénient au C++ que je vie en tant que directeur. L'introduction d'un nouveau membre à l'équipe de programmation exige un formation intense sur notre façon de travailler, concevoir et coder. Cette formation est ardue, spécialement pour un débutant, mais croyez-moi mon expérience, ce temps est un investissement pour lui et la compagnie car les bénéfices à long terme sont immenses.
    a- Euh... La lib standard est standard depuis 98... Certes on n'avait pas std::unique_ptr, mais std::auto_ptr (qu'il fallait coupler avec boost::ptr_vector), std::vector, std::string, les flux... Début 2000, boost nous a aussi apporté boost::scoped_ptr et boost::shared_ptr, en attendant la sémantique de déplacement.

    3- Oui! Le C++ moderne est ce qui fait toute la différence. Savoir enseigner la cuisine sans passer par la taille du silex parce que c'est comme ça que l'on faisait avant...
    J'ai passé je ne sais combien de temps ici et ailleurs, déjà avant 2011, à pousser à rompre avec l'héritage du C pour moderniser notre approche du C++ et son enseignement. Je valide complètement.

    Toutefois, on a toujours deux gros soucis non triviaux et non gérés par le langage: les aliasings, et les use-after-move car l'objet existe toujours : il n'est pas `del` comme en Python.
    (Après il parait que Rust élimine les data-races, mais je suis sceptique comment le langage peut gérer les races au niveau métier -- ça me fait penser à ces critiques comme quoi les conteneurs de la SL ne sont pas thread-safes alors que la cohérence c'est bien plus subtil qu'ajouter ou retirer un élément. Mais peut-être que je me trompe et qu'il y a un équivalent natif de la preuve de concept d'Andrei Alexandrescu autour des fonctions membres volatiles, qui devait être opt-in)

    c- Oui. Il est souvent nécessaire de former.
    Après, les formations que je donne en interne sont loin de ne parler que de syntaxe. Je passe beaucoup de temps à reprendre les fondements objets, les bonnes pratiques associées, le besoin de libération déterministe, les contrats VS validation des inputs VS prog défensive... Bref, plein de trucs sans rapport direct avec le C++.


    Citation Envoyé par jo_link_noir Voir le message
    mais le C++ moderne (qui a plus de 10 ans maintenant)
    Au moins 22ans: https://www.artima.com/articles/modern-c-style

    Après... tous les 3 ans il se modernise encore. Mais la rupture de style (RAII + SL + exploitation du typage), était là il y a déjà longtemps.

    A propos ça fait longtemps qu'il y a des sortes de modes "hardened" dans les implémentations de la SL. Mais si je comprends, la différence est que maintenant l'ABI reste compatible selon le mode de défensivité de la SL qui est choisi lorsque l'on compile?
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  14. #34
    Membre confirmé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2021
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2021
    Messages : 114
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    Après il parait que Rust élimine les data-races
    Oui, et c’est précisément là que Rust se distingue : les data races sont éliminées par construction, non pas par ajout d’outils externes ou d’analyse dynamique, mais en intégrant dans la sémantique même du langage la condition d’absence de data race.

    Plus précisément, le modèle de propriété et d’emprunt (borrowing) encode formellement ce qu’est une data race :

    “Un accès concurrent à une donnée, dont au moins un est mutable”
    devient :
    “Soit un accès mutable exclusif, soit plusieurs accès immuables, mais jamais les deux à la fois”

    Cette règle est vérifiée statiquement par le compilateur, ce qui permet de garantir l’absence de data races sans coût d’exécution, et sans mécanismes comme les verrous implicites ou les analyseurs de course.

  15. #35
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 308
    Par défaut
    OK. Je lis que Rust distingue data-race et race-condition. Vu que je range ces erreurs dans le même paquet je comprends pourquoi je ne voyais pas ce que Rust pouvait faire pour moi -- que ma corruption soit logique ou plus profonde, je considère que mon programme ne peut rien produire d'utile, voire qu'il peut tout autant saboter des résultats.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  16. #36
    Membre confirmé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2021
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2021
    Messages : 114
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    OK. Je lis que Rust distingue data-race et race-condition. Vu que je range ces erreurs dans le même paquet je comprends pourquoi je ne voyais pas ce que Rust pouvait faire pour moi -- que ma corruption soit logique ou plus profonde, je considère que mon programme ne peut rien produire d'utile, voire qu'il peut tout autant saboter des résultats.
    Le data race est une notion formalisée, localisable, et encodable dans un système de types (comme celui de Rust), alors que la race condition, au sens large, est une classe plus générale d’erreurs concurrentes, sans définition universelle ni cadre d’analyse unique.
    Les deux sont indécidables en toute généralité, mais Rust, en restreignant le langage par son système de propriété et d’emprunts, rend la détection (et même l’élimination) des data races décidables par construction.

    Et c’est peut-être là la vraie logique de Rust :
    --> automatiser ce qui est formalisable (data race),
    --> laisser la logique métier, l’ordre des événements, et les choix de synchronisation entre les mains du développeur.

  17. #37
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    405
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 405
    Par défaut
    Il y a 20 ans, on expliquait à ceux qui faisaient du C en quoi c'était pertinent de passer au C++. Et ils répondaient avec des arguments... "criticables".

    Maintenant, c'est les devs C++ qui défendent leur langage avec les mêmes arguments utilisés par les devs C il y a 20 ans.

    Ca me laisse perplexe.

    Signé : un dev C++, qui ne veut pas non plus passer à Rust, mais qui n'adhère pas du tout à certains arguments de ceux qui défendent le C++.


    "Pourquoi cherche-t-on la facilité?"
    "C'est saoulant ce délire du besoin du code parfait."
    "Cette sévérité sélective à l'égard du C et C++ sur cette obsession de la gestion mémoire me parait excessive."

    Quand je vois ce genre de commentaires, je me dis qu'il est probablement préférable d'imposer un langage avec des contraintes qui imposent la sécurité, plutôt que laisser les devs faire selon leur bon vouloir.

  18. #38
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 308
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 308
    Par défaut
    Citation Envoyé par mintho carmo Voir le message
    Il y a 20 ans, on expliquait à ceux qui faisaient du C en quoi c'était pertinent de passer aux C++. Et ils répondaient avec des arguments... "criticables".

    Maintenant, c'est les devs C++ qui défendent leur langage avec les mêmes arguments utilisés par les devs C il y a 20 ans.
    Il y a une petite différence, il est relativement aisé d'introduire graduellement des features du C++ dans un code C.

    Passer à Rust... il faut repartir de zéro. Perdre des features... Mais oui. On progresse vers plus de sécurité sans sacrifier les perfs contrairement à d'autres langages.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  19. #39
    Membre confirmé
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Mai 2021
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mai 2021
    Messages : 114
    Par défaut
    Citation Envoyé par Luc Hermitte Voir le message
    il faut repartir de zéro. Perdre des features...
    Je viens de me plonger dans les évolutions du standard depuis C++11.
    Je me suis limité aux grandes lignes, évidemment, mais il y a beaucoup d'équivalence C++ / Rust (je ne parle pas des caractéristiques propres évidentes Class <-> traits, sémantique de prêt, ...).
    Pour ce qui est de certaines fonctionnalités rajoutées aux C++, il y a souvent des équivalents qui me paressent mieux en Rust: par exemple le fonctionnel et le pattern matching.
    En lien avec les coroutines, il y a en Rust: une bonne prise en charge des évaluations différées ; des fonctionnalités en programmation asynchrone non bloquantes plus abouties, à mon avis, qu'en C++ (notamment des runtimes quasi standards) ; les générateurs sont encore nightly (même s'il y a des crates proposant des alternatives) ; et bien d'autres équivalents aux usages des coroutines. Par contre, la philosophie n'est pas de faciliter l'accès à des fonctionnalité de coroutines générales (pour des raisons de sécurité, d'ailleurs).

    Etc.

    Ce qui freine l'adoption du langage est certainement le coût d’acquisition d'une compétence équivalente, et les historiques de projets.

  20. #40
    Membre émérite

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    405
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 405
    Par défaut
    Citation Envoyé par fdecode Voir le message
    mais il y a beaucoup d'équivalence C++ / Rust\
    Je pense que lmghs dit cela dans le sens où Rust impose des contraintes pour garantir le code et que ces fonctionnalités qui sont "retirées" (*) rendent le transfert du code C++ vers Rust plus compliqué qu'une simple réécriture du code. Ca oblige a repenser le design du code (**) et donc un travail supplémentaire.

    (*) sans utiliser unsafe, ce qui ferait perdre l'intérêt de passer a Rust.
    (**) je ne dis pas par la qu'un redesign serait une mauvaise chose, loin de la. Au contraire, même si on reste en C++, refaire un design peut etre parfois une solution pertinente pour regler des problemes de safety. Mais dans tous les cas, un redesign impose un travail supplémentaire.

Discussions similaires

  1. Réponses: 16
    Dernier message: 04/11/2007, 14h51
  2. scroll disparaissant quand pas besoin
    Par nebil dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 29/10/2007, 20h57
  3. pas besoin de synchronisation?n'est ce pas
    Par erman_yazid dans le forum EDT/SwingWorker
    Réponses: 3
    Dernier message: 17/04/2007, 10h02
  4. Réponses: 10
    Dernier message: 11/03/2007, 13h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo