pasBill pasGates a écrit 16062 commentaires

  • [^] # Re: Je pense que tu confonds les cas où c'est nécessaire

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 2.

    Donc tu vas faire des checks seulement la moitie du temps dans ton code ? Tu vas te retrouver avec un code qui se comporte correctement la moitie du temps et qui explose l'autre moitie ? Tu vas te poser la question a chaque fois de ce que tu dois faire (verifier ou pas) plutot que simplement le faire systematiquement ?

    Desole mais je ne vois vraiment pas ce que t'y gagne.

  • [^] # Re: Je pense que tu confonds les cas où c'est nécessaire

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 0.

    Je n'ai jamais chargé un fichier avec malloc directement, j'aimerais que tu m'expliques le rapport entre allouer une zone mémoire et un fichier. Tu charges le fichier avec fopen normalement… Or je ne parle que de malloc ici.

    Quand tu charges des donnees d'un fichier, tu les stockes ou ? En memoire le plus souvent, memoire qu'il faut allouer.

    Je parle d'une petite allocation de quelques octets, pas d'une matrice…

    Si tu sais d'avance qu'elle est petite oui, mais combien y a t'il de cas ou tu sais de maniere garantie qu'elle sera petite ? Combien sont de taille dynamique, ou la valeur vient de l'exterieur (Content-Length header d'une requete HTTP, taille de fichier, taille de tableau lue dans un fichier, valeur specifiee par l'utilisateur, etc…)

  • # Les auteurs

    Posté par  . En réponse à la dépêche QubesOS 1.0. Évalué à 10.

    A noter que les auteurs originels de ce systeme sont Joanna Rutkowska et Rafal Wojtczuk , qui ont notamment ete a l'origine de blue pill (rootkit a base d'hyperviseur) et red pill (methodes de detection de rootkit a base d'hyperviseur). Ce sont loin d'etre des idiots dans le domaine de la securite, la presentation de Johanna sur Blue Pill a BlackHat a notamment du avoir un sacre effet sur tout programmeur mysogine qui l'a vu, j'y etais et probablement les 8 ou 9 dixiemes de la salle etaient incapable de suivre tellement c'etait bas niveau et avance (moi compris).

  • [^] # Re: Je pense que tu confonds les cas où c'est nécessaire

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 1.

    Ton app charge un fichier qui il se trouve est corrompu.
    Le format contient quelque chose du genre [taille du tableau][tableau]

    Ton app, pour charger le tableau va lire la taille et essayer de faire une allocation pour y stocker le tableau. Si la taille est corrompue (genre 0xFFFFFF0 ou autre truc enorme), ton soft va essayer de faire une allocation enorme, qui va rater meme si ta machine a encore plein de RAM dispo.
    Est-ce que le soft devrait planter dans un cas pareil ? Non, il devrait voir qu'il n'arrive pas a lire le fichier et renvoyer une erreur a l'utilisateur mais si on lit certains ici, planter est la solution parait-il…

  • [^] # Re: Et printf ?

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 3.

    Ça suppose quand même d'avoir une grande base de code d'erreurs unifiés pour permettre la propagation assez simplement

    Ca existe deja, suffit de reutiliser(Win32 en contient des centaines par exemple).

    Ça veut dire aussi qu'il faut convertir tous les cas d'erreurs des libs externes qu'on appelle.

    Oui et non, ca depend de la granularite des erreurs que tu veux gerer, et sous Windows au moins c'est souvent transparent vu qu'il y a "une" liste standard d'erreurs.

    Cela étant dit, je tends plutôt vers une approche à la Zenitram: au quotidien, très peu de soft que j'écris est critique, on est soit dans la ligne de commande, soit dans l'appli graphique à deux balles. Et donc la gestion de ce genre d'erreur me passe un peu au dessus.

    Je veux bien que ce soit pas critique dans ce cas, mais faire cela :
    a) T'empeche de reutiliser ce que tu as ecrit dans quelque chose de plus important
    b) Te donne des mauvaises habitudes je dirais, qui rende l'ecriture de code "critique" plus risque

    Mon point de vue est que ces checks sont de toute facon tres rapide a ajouter(il y a quasiment toujours des chemins d'erreurs pour d'autres raisons, suffit donc de les reutiliser) et qu'au final cela coute tellement peu a faire qu'il vaut mieux le faire systematiquement.

  • [^] # Re: Je pense que tu confonds les cas où c'est nécessaire

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 10.

    J'ai aussi une info de dernière fraicheur pour toi : une doc n'est jamais à jour, toujours obsolète, toujours incohérente, toujours incomplète, voire même inexistante.
    Celui qui te dira le contraire est un fou.
    Si tu persistes encore à maintenir le contraire, prend n'importe quelle doc de ton choix et prouve-moi qu'elle est non seulement correcte, mais en plus exhaustive de tout ce qui peut se passer via n'importe quel cas d'utilisation.

    Ah ben voila, quelle logique ! Une doc peut avoir des erreurs, donc en toute logique : il ne faut jamais utiliser la doc !
    Tu sais qu'un compilateur peut avoir des bugs, pourquoi tu en utilises un alors ?

    Tout ce qu'un développeur peut te dire au sujet de ce code, et en particulier la doc, est tout autant soumis aux bugs du développeur que le code lui-même.
    Un développeur peut très bien ne pas s'apercevoir d'un effet de bord de son code, et ne le documentera donc pas.

    Super, ca ne change absolument RIEN au fait que la doc est utile, qu'elle donne plein d'informations correctes, et qu'elle evite de faire des erreurs.

    Je développe des softs toute la journée, et la qualité logicielle est justement une de mes préoccupations principale.
    Et pour te résumer ma position de manière succinte : le C et consort, c'est mal; le duck-typing, c'est mal; le non-typé, c'est mal.

    C'est pas ce que je t'ai demande, je t'ai demande en quoi je devrais suivre tes dires plutot que ceux des devs du kernel Linux ou de chez Microsoft. Tu as quoi comme experience de gros developpements de qualite et a succes qu'ils n'ont pas ?

    Pour le cas qui nous concerne, les check-exceptions sont pour moi le meilleur moyen de résoudre le problème qui nous inquiète.
    Si on regarde le problème initial :
    - Dans 99% des cas, on ne sait pas quelles erreurs peuvent arriver pour chaque ligne du programme. Cf supra, la doc ne peut pas aider sur ce point;
    - Dans 99% des cas, on ne sait pas gérer une erreur au niveau où l'on est, et on devra la propager au niveau supérieur, jusqu'à ce que quelqu'un sache la gérer;
    - Dans les cas les plus graves (null pointer exception, out of memory, buffer overflow…), on sait pertinemment que rien ne sert de tenter le moindre rétablissement, on est mort, autant s'arrêter.

    Tu as faux sur toute la ligne. Je dis bien, toute la ligne, et j'ai des millions de lignes de code presentes sur 1 milliard de machines qui le prouvent. Je t'ai meme presente plus haut pourquoi il n'y a pas besoin de connaitre toutes les erreurs pour pouvoir les gerer.

    Plutôt que d'avoir du code ignoble et inmaintenable à écrire sur chaque ligne et pour chaque erreur possible et/ou avoir à écrire la propagation supérieure et/ou avoir à gérer l'arrêt du programme, et ce sur chaque méthode, chaque appel de méthode et chaque programme, ça devrait être au compilateur de faire ce travail.

    Ah ben oui, parce que le compilateur est sense savoir comment tu veux gerer une erreur ? Le compilateur est meme sense savoir ce qu'est une erreur ? Serieux, tu developpes vraiment professionellement ?

    Si on prend les exceptions à la Java, on règle d'un coup tous les problèmes :
    - Chaque méthode déclarant toutes les exceptions qu'elle peut lever, aucun risque d'en oublier une seule;
    - Si une erreur peut arriver, alors on a que 2 choix, soit on sait la traiter et on la traite, soit on ne sait pas et on la laisse remonter, en déclarant que notre propre méthode peut échouer;
    - Dans les cas les plus graves, le système lève une exception non-contrôlée, qui remontera toute seule toute la chaîne d'appel et arrêtera le programme.
    C'est le compilateur qui fera tout le travail ingrat, proprement et sûrement, de manière mutualisée, évitant au développeur de réinventer la roue (carrée, de préférence…).

    Vraiment ? Tu connais les problemes du traitement en exceptions ? Sont cout en performance, la difficulte d'eviter des leaks et autres quand l'exception se produit apres que tu aies alloue des ressources, pris des locks, etc… ?
    Le systeme par exception n'a pas vraiment plus d'avantages ni d'inconvenients, c'est une autre approche simplement.
    Ton 'truc' ou les erreurs que tu ne connais pas sont remontees c'est exactement ce que je t'ai montre plus haut en C. Mon code fait exactement la meme chose : une erreur inconnue est remontee aussi.
    Et non le compilo ne fait pas tout le travail ingrat, le compilo ne sait pas liberer des ressources prises avant l'exception, il ne sait pas liberer un lock, etc…

    Voilà comment faire les choses proprement : déléguer au compilateur le maximum possible de vérification.
    Un compilateur ne fera pas d'erreur, un développeur en fera obligatoirement une.

    Un compilateur peut faire des erreurs (et oui, ca existe), mais en plus, un compilateur ne sait pas gerer les erreurs, du tout.

  • [^] # Re: criticité

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 4.

    Parce que tu sais d'habitude comment ton soft va etre utilise ?
    Prends un soft de conversion basique : il prend un fichier en entree, et en ressort un autre.
    Il ne fait que lire le fichier d'entree, resultat il ne risque pas d'endommager quoi que ce soit.
    Tu te mets a coder comme tu dis, sans verifier si les allocations reussissent, etc… parce que bon, si l'utilisateur il voit son soft exploser en vol c'est pas grave apres tout, il n'a rien perdu hein.

    Le probleme est quand ton utilisateur se met a faire des batchs de ta commande par divers moyen (shell, etc…), il n'aura aucune idee qu'il y a eu un probleme dans le fichier 468, il ne saura pas ce qui a cause le probleme, etc…

    Idem pour le gars qui se decide de creer un service de conversion sur le web, il va passer des fichiers venant de l'exterieur a ton soft de conversion, et devine quoi, ton petit soft pas important va devenir une faille de securite sur le systeme de l'utilisateur car tu ne verifies pas que tes allocations fonctionnent.

    Alors si tu parles d'un petit gadget de 100 lignes oui qui affiche l'heure, oui ca revient a taper sur un moustique avec un martinet, mais vu l'effort supplementaire que ca demande qui est minimal mieux vaut le faire parce que c'est une habitude a prendre plus qu'autre chose. Le jour ou tu te mettras a coder un truc plus gros, tu feras la chose correctement de maniere instinctive plutot qu'inserer des erreurs a tout bout de champs a cause de tes mauvaises habitudes precedentes.

  • [^] # Re: Je pense que tu confonds les cas où c'est nécessaire

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 9.

    C'est pas parce que tout le monde fait comme ça qu'il faut faire comme ça…

    Je serais ouvert a ecouter tes experiences sur le sujet relativement aux gros projets software et a leur success / qualite. Si tu as mieux, n'hesites pas.

    Sinon, ça veut dire que Windows est meilleur que Linux ?

    Vu que le kernel le fait aussi, comme je l'ai dit, non, ca veut dire que les 2 font comme il faut.

    En temps que développeur d'une application, tu es utilisateur des API de plus bas niveau.

    J'ai bien compris, et devines quoi, le developpeur doit lire la doc des APIs aussi, histoire de comprendre quels effets de bord ils peuvent avoir, dans quel cas ils peuvent se rater, etc…

  • [^] # Re: criticité

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 1.

    OK, donc explique-moi ce que tu pourrais faire de plus qu'un _exit() en cas de OOM sur ce programme précis (parce qu'on parle de celui-là, toute la question est de la pertinence d'une telle gestion en fonction de la criticité). Si ton programme ne peut plus fonctionner correctement, autant le terminer pour remonter l'erreur que de continuer et faire n'importe quoi, non (encore une fois, je parle de programmes non critiques) ?

    Mais qui t'a dit qu'il ne peut plus fonctionner correctement ? Ce soft peut liberer des buffers qu'il detient et re-essayer, simplement abandoner le chargement du fichier qu'il etait en train de lire et continuer de travailler avec les autres documents qu'il a charge, etc…

  • [^] # Re: Je pense que tu confonds les cas où c'est nécessaire

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 9.

    on en arrive à une 15aine de lignes de code et une complexité de 4.
    Sur un soft d'une complexité standard, je te laisse imaginer ce que ça donne…

    La realite est que cette methode est utilisee dans certains des plus gros projets software existants (Windows et Office au hasard ainsi que le kernel Linux) et que ca marche tres bien.

    Idem en maintenance/évolution, alors que sur le pseudo-code on n'aurait qu'à ajouter une ligne entre foo() et bar(), en C on va devoir toucher aussi à toute la partie nettoyage/gestion d'erreur, aussi bien dans notre code que dans le code appelant. Idéal pour semer des régressions aux 4 coins de l'appli…

    Et pourquoi tu aurais besoin de changer le code appelant ? Tout ce que le code appelant a besoin de savoir est que ca a rate, il peut aller de maniere plus granulaire pour peut-etre re-essayer, logger un message plus precis, … mais le simple fait de savoir que la fonction a echoue est suffisant, bref, un switch-case avec un 'default' fait le boulot ou un if (ret==success) else {} aussi.

    Au niveau développement, l'utilisateur d'une API n'a aussi aucune garantie de gérer toutes les erreurs possibles et imaginables que peut lui retourner une fonction, sauf à aller lire la doc (généralement fausse et/ou incomplète) voire pire, carrément le code source…

    La beaute est justement que c'est totalement optionel. Le minimum a faire est voir que la fonction a reussie (tu compares au code de reussite), ensuite si tu veux gerer specifiquement qqe erreurs ou toutes les traiter de la meme maniere, c'est ton choix, mais tu sauras que la fonction a echoue:

    DWORD dwResult=MyFunction();
    switch(dwResult)
    {
      case ERROR_SUCCESS:
        break;
      case ERROR_BROKEN_PIPE:
        delete[] FrameBuffer;
        if (CheckConnection())
          return Retry();
        else return dwResult;
      case ERROR_NOT_ENOUGH_MEMORY:
        log("pas assez de memoire\n");
      default:                        //toutes les erreurs non gerees specifiquement finissent ici
        delete[] FrameBuffer;
        return dwResult;
    };
    
    

    Sinon, ta phrase "l'utilisateur d'une API n'a aussi aucune garantie de gérer toutes les erreurs possibles et imaginables que peut lui retourner une fonction, sauf à aller lire la doc (généralement fausse et/ou incomplète)" est franchement horrible, oh mon dieu, l'utilisateur doit lire la doc ? Grande nouvelle, si il ne l'a lit pas, mieux vaut qu'il n'ecrive pas de code !

  • [^] # Re: criticité

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 8.

    Mais pour faire les choses proprement, par exemple prévenir l'utilisateur, ou sauvegarder le fichier, et bien il faut de la mémoire.
    Bah oui, créer un popup, ça demande de la mémoire. fprintf() utilise malloc(), tout comme fwrite() (oui je connais setvbuf()), etc. Quand tu y penses, sans malloc(), il ne te reste plus grand chose de disponible.

    Ca depend des cas, comme tout. Si ton soft voit son alloc echouer alors que tu es en train de charger un 14eme document, ben il abandonne et vide tout ce qu'il a alloue pour le 14eme, et il evite de tout crasher et forcer l'utilisateur a rouvrire les 13 premiers documents, c'est un avantage indeniable.

    Bref, gerer les mallocs qui ratent, ca ne coute quasiment rien, et ca peut rapporter gros.

  • [^] # Re: Je pense que tu confonds les cas où c'est nécessaire

    Posté par  . En réponse au journal Genèse d'un journal. Évalué à 10.

    La plupart des APIs ont la possibilite d'echouer, pour diverses raisons (mauvais parametres, rates reseau, etc…)

    Faire :

    buffer=malloc(X)
    if (!buffer)
    {
      return ERROR_NOT_ENOUGH_MEMORY;   //  ou
      dwResult=ERROR_NOT_ENOUGH_MEMORY;
      goto cleanup;
    }
    
    

    ca prend quoi ? 5-10 secondes de plus, bref, rien de serieux niveau effort, et ca a l'avantage de permettre une gestion propre, avec un utilisateur qui ne voit pas ses softs exploser sans savoir pourquoi.

  • [^] # Re: Bien, mais l'obligation....

    Posté par  . En réponse à la dépêche Modification du code des marchés publics italien imposant l’usage du logiciel libre. Évalué à 4.

    Ta page est un amas de conneries non-fondees, et l'a toujours ete.

    Exemple simple: l'affirmation que MS detient la plupart des anti-virus, il faut vraiment etre sacrement incompetent ou de sacrement mauvaise foi pour sortir une anerie pareille.

  • [^] # Re: Ne le fait pas.

    Posté par  . En réponse au journal realloc. Évalué à 0.

    Tu attaches un debugger, tu mets un breakpoint sur msvcrt!malloc, quand le breakpoint est touche, tu regardes l'assembleur juste apres l'appel, et tu verras une comparaison sur le registre eax, qui est le registre contenant la valeur de retour…

  • [^] # Re: Ne le fait pas.

    Posté par  . En réponse au journal realloc. Évalué à 0.

    De nouveau, rien a voir.

    malloc te retourne null si l'espace memoire de Firefox est fragmente et si il tente un gros alloc, meme si il reste plein de RAM. OOM-killer ne levera pas un doigt dans ce cas.

  • [^] # Re: Ne le fait pas.

    Posté par  . En réponse au journal realloc. Évalué à 0.

    Ils sont tres nombreux oui, a peu pres tous les softs serveurs, et chez nous tous les autres softs aussi(du moins tout ce qui est dans Windows et Office). Si on voit ca en code review c'est immediatement marque comme "a corriger" (et evidemment on en rate quelque uns qui atterissent dans le produit, on est pas parfait)

  • [^] # Re: Ne le fait pas.

    Posté par  . En réponse au journal realloc. Évalué à 3.

    Alors vu qu'il y a une possibilite qui existe que ca merde et corrompe le fichier (prise de courant), autant ne jamais gerer les problemes d'allocation et laisser le fichier etre corrompu dans tous les cas ?

    On va aller loin avec une approche pareille, et tu en fais quoi du fait que l'utilisateur n'a aucun moyen de comprendre ce qui s'est passe ?

    Qu'il doit se retaper ce qu'il a perdu avec les softs qui n'ont pas d'auto-save ? (et le soft pourrait planter au milieu de l'auto-save hein…)
    Que cette approche a la porc ouvre la porte a plein de failles de securite ?
    Que cette approche peut corrompre la configuration du soft et l'empecher de redemarrer plus tard ?
    etc…

  • [^] # Re: Ne le fait pas.

    Posté par  . En réponse au journal realloc. Évalué à 0.

    Tu penses ?

    Tu es en train de mettre la derniere touche a ton livre de 400 pages, et tu as Firefox en arriere plan qui bouffe toute la RAM, alors que OpenOffice essaie de sauver, il se retrouve avec un malloc qui rate, tu penses qu'il devrait exploser en vol et corrompre le document ou s'en sortir proprement ?

  • [^] # Re: Ne le fait pas.

    Posté par  . En réponse au journal realloc. Évalué à 3.

    Arreter le programme peut-etre oui, selon ce que le soft fait, mais il faut le faire proprement , pas avec un SEGFAULT ou un assert.

  • [^] # Re: Ne le fait pas.

    Posté par  . En réponse au journal realloc. Évalué à 4.

    Ben t'as un chemin d'erreur normalement, si ton allocation rate, tu defais ce que tu avais fais et tu retournes une erreur.

    Il y a forcement de tres rares cas ou il faut fermer l'application/tuer le systeme, mais dans ces cas-la, faut le faire le plus proprement possible (tu fermes les fichiers que tu ecris, tu logges un msg d'erreur, tu informes l'utilisateur, etc…)

    Pour C++ normalement tu peux faire ton new avec std::nothrow qui forcera l'allocateur sans exception (tu recevras un NULL a la place), mais le defaut est de lancer une exception.

    Quand a l'exception, ca va quitter le programme oui, mais c'est de nouveau pas forcement le bon resultat a avoir…

  • [^] # Re: Ne le fait pas.

    Posté par  . En réponse au journal realloc. Évalué à 10.

    Non franchement non, pas d'accord.

    Le BABA du programmer correct est la gestion d'erreur. Une allocation de ressource qui flanche ca arrive, et ca doit etre gere. Ton utilisateur quand il voit ton soft lui exploser dans les doigts, c'est vraiment pas ce qu'il attend et il ne comprendra meme pas pourquoi, sans parler du fait qu'il y a risque de faille de securite (selon les operations faites apres l'alloc) si tu ne le geres pas.

  • [^] # Re: Ne le fait pas.

    Posté par  . En réponse au journal realloc. Évalué à 10.

    Euh non desole, c'est une question d'hygiene de base de mon point de vue.

    Le dev qui laisse aller des trucs aussi basique, c'est vraiment qu'il se fiche de son code, qu'il ne pense pas loin et qu'il a certainement plein d'autres problemes dans son code.

    Ton bete outil, il va un jour etre utilise a travers Apache par exemple, avec parametres passes par l'utilisateur parce qu'apres tout, ton outil est juste genre un convertisseur ou autre.
    Et le jour ou ton malloc il va rater et tout le monde s'en fiche, ben tu te retrouves avec une faille de securite potentiellement exploitable selon les operations faites apres le malloc.

  • [^] # Re: Ne le fait pas.

    Posté par  . En réponse au journal realloc. Évalué à 2.

    Le mieux que tu puisse faire c'est un truc du style
    C
    assert(src_dup);

    Euh non, parce que si tu fais ca, en cas d'echec d'allocation, ton programme il meurt. Tuer un soft parce qu'une allocation a echoue c'est franchement crade, tu avortes la requete ou l'operation, tu logges une erreur si besoin est, mais tu continues de tourner.

  • [^] # Re: Tant que ça reste coté Desktop...

    Posté par  . En réponse à la dépêche Le point sur udev et systemd. Évalué à 2.

    Ben ce sont justement celles que l'on retrouve dans Unix dès les années 70 et qui ont fait grandement son succès : modularité de l'espace utilisateur avec communication inter module, tout est fichier (de nos jours : objets, fonctions, ressources WEB, bref il y en a pour tous les goûts), etc. Marrant non ?

    Ah oui, tres marrant.

    Combien de softs importants sont composes de petits executables communiquant par pipe avec du texte comme mode de transport ? FireFox ? OpenOffice ? Apache ? Eclipse ? KDE ? Gnome ? Ah ouais, on voit combien cette architecture est suivie de nos jours…

    Les softs d'aujourd'hui sont modulaires, mais en tant que dll charges(= plugins) plutot que differents executables, les configurations sont de moins en moins shell / texte pour etre plus structurees, etc…

    Le web tu trouves que c'est KISS ? Avec SVG, la 3D, javascript, XML, CSS, SSL etc… dedans ? On dirait un mini-OS a la Emacs.

    etc…

  • [^] # Re: Tant que ça reste coté Desktop...

    Posté par  . En réponse à la dépêche Le point sur udev et systemd. Évalué à 3.

    Plus généralement, l'essence d'UNIX c'est
    - KISS,
    - "Tout est fichier",
    - "Tout est éditable" (pas de binaires hormis les exécutables/librairies/images…),
    - Un outil s’acquitte d'une tâche et d'une seule etc …

    Voila ce que je pense des dogmes :
    Ben...

    Non pas que la philosophie est totalement stupide hein, mais faudrait penser a evoluer un peu, l'informatique des annees 60 n'a plus rien a voir avec celle du 21eme siecle.