lasher a écrit 2732 commentaires

  • [^] # Re: et ca compile ?

    Posté par  . En réponse au journal OpenSSL est mort, vive (le futur) LibreSSL. Évalué à 5.

    Qu'ils utilisent des fonctions de leur OS est tout à fait compréhensible, mais il ne faut pas « justifier » ce fait en disant « de toute manière les systèmes BSD ont cette fonctionnalité ».

    Par contre, du peu que j'ai pu voir du code des différents BSD, il y a généralement un gros effort d'encapsulation qui rend le code non seulement lisible, mais (relativement) facilement portable. Dans le cas de funopen, il est possible de reproduire la fonctionnalité, mais sans doute avec une efficacité moindre (puisque funopen peut « jouer » avec les différents flux, alors que faire la même chose directement avec des descripteurs de fichiers et read/write nécessite de maintenir les flux de lecture/écriture complètement séparés).

    C'est un peu comme strlcpy et strlcat. La fonction n'est pas du C standard (même pas POSIX) et donc pas forcément disponible sur le système cible, mais proposer une implémentation de secours n'est quand même pas si compliqué (bon, funopen demande un peu plus de cogiter).

  • [^] # Re: Vérification formelle

    Posté par  . En réponse au journal Idée stupide sur la sécurité du code. Évalué à 4.

    Vous n'avez pas forcément la même notion de ce qui est critique. :-)

    De plus, même lorsque la performance est effectivement critique, disons dans l'embarqué, il y a tout un tas de choses interdites même si le C les autorise : allocation dynamique, récursion, etc.

  • [^] # Re: Implémentation prouvée

    Posté par  . En réponse au journal OpenSSL est mort, vive (le futur) LibreSSL. Évalué à 5.

    On ne peut pas prouver que tous les algorithmes sont corrects. Il faut les contraindre à accepter tout un tas de paramètres pour rendre l'espace de recherche pour la preuve acceptable. Et puis aussi, si ce que tu avances est vrai, on pourrait prédire quand un algo se termine dans le cas général, ce qui n'est pas possible (le problème de l'arrêt est indécidable).

  • [^] # Re: Et les algorithmes GOST ?

    Posté par  . En réponse au journal OpenSSL est mort, vive (le futur) LibreSSL. Évalué à 10.

    Je pige pas bien. AES, comme à peu près tous les algos de crypto publics, a été et est encore testé dans ses retranchements en permanence. Lorsque le « challenge » pour choisir l'algo qui allait être choisi pour AES a été émis, la compétition était clairement ouverte à tous les « non-guignols » (i.e. à ceux qui savent établir un protocole de crypto symmétrique).

    Donc s'il n'existe pas de preuve formelle qu'il n'y a pas de backdoor dans AES, il y a par contre un historique de ~15 ans de recherche, où l'on a essayé de casser de l'AES à tour de bras.

    C'est un peu comme si tu disais qu'on n'a pas prouvé que RSA n'avait pas de backdoor. C'est vrai, mais on a démontré tout un tas de cas où le protocole casse si l'on choisit mal les clés privées ou publiques. Et du coup on a « patché » le protocole en conséquence.

  • [^] # Re: et ca compile ?

    Posté par  . En réponse au journal OpenSSL est mort, vive (le futur) LibreSSL. Évalué à 10.

    Non mais regarde par exemple le noyau linux à l'époque des 2.x (x ≤ 4): le portage avait plus ou moins nécessité une réécriture complète de certaines portions du noyau pour chaque nouvelle architecture visée. Alors qu'à partir du noyau 2.6, comme un gros effort de nettoyage de code, de factorisation, etc., avait été apporté, le plus gros avantage avait finalement été (au moins au début) la meilleure portabilité du code, ce qui permettait de modifier le noyau en un endroit et de ne devoir dupliquer certaines modifications que bien plus rarement.

    Autre exemple : le code de NetBSD (et en fait, OpenBSD itou de ce que j'ai pu voir) est considéré comme extrêmement portable, car même les drivers sont écrit en C ISO (+POSIX je suppose), avec une quantité de code assembleur extrêmement limité, ceci grâce à l'utilisation de wrappers (fonctions d'adaptations) « légers » qui parlent le « langage » de l'OS (bref, qui pigent ses API), et qui évitent voir interdisent l'utilisation de code ASM directement.

    Imaginons un code de ce genre :

    /* Ce code est sans doute mal synchronisé; je l'utilise juste pour l'exemple. */
    extern volatile int g_lock;
    
    /* Tentative de prise de verrou */
    #if defined(HAS_COMPARE_AND_SWAP)
    while (compare_and_swap(g_lock,0,1) != 1)
        ; // do nothing: busy waiting -- bad programmer, no cookie !
    #elif defined(HAS_TEST_AND_SET)
    while (test_and_set(g_lock) == 1)
        ; // do nothing: busy waiting -- bad programmer, no cookie !
    #endif
    
    /* plus loin dans le code ... */
    
    /* Libération du verrou */
    #if defined(HAS_COMPARE_AND_SWAP) || defined(HAS_TEST_AND_SET)
    g_lock = 0;
    #endif

    Il est évident que ce truc n'est pas portable. Le code de verrouillage/déverrouillage devrait être encapsulé dans des fonctions spécifiques (par exemple, mutex_lock() et mutex_unlock()1), et encore mieux, il faudrait « fabriquer » un compare_and_swap à partir d'un test_and_set si C&S n'existe pas sur l'archi cible, comme ça le code ne pourrait jamais casser, même si en pratique il risquerait de perdre en perf (car du coup pour fabriquer un C&S à partir d'un T&S, tu dois utiliser une variable tierce pour modifier le mot, faire le test, et renvoyer l'ancienne version).

    Note que mon exemple est complètement artificiel, vu que gcc et ses potes (au moins llvm et icc, mais sans doute les autres compilos aussi) ont déjà des intrinsics pour générer le bon code. Cela dit, l'OS devrait enrober ces opérations malgré tout pour assurer la portabilité du code au-delà de l'usage d'un compilateur en particulier.


    1. Et je ne parle même pas de l'utilisation d'une variable globale… 

  • [^] # Re: C'est pourtant évident.

    Posté par  . En réponse à la dépêche Coder efficacement, bonnes pratiques et erreurs à éviter. Évalué à 2.

    Intéressant ! Il y a aussi deux chercheurs italiens (L. Verdoscia, et R. Vaccaro) qui essaient de construire une machine à base du modèle d'exécution de dataflow1, et qui voudraient utiliser le langage fonctionnel proposé par J. Backus comme langage « bas-niveau » (comprendre : une sorte « d'assembleur » fonctionnel).


    1. Par contre désolé, c'est derrière un paywall… 

  • [^] # Re: C'est pourtant évident.

    Posté par  . En réponse à la dépêche Coder efficacement, bonnes pratiques et erreurs à éviter. Évalué à 1.

    J'aurais dû préciser que ma réponse était un peu facile. :-)

    Mais oui, Emacs pourrait sans doute être qualifié. Mais je croyais qu'il avait été récrit en C (et qu'il avait « juste » un moteur elisp) ? ;-)

  • [^] # Re: C'est pourtant évident.

    Posté par  . En réponse à la dépêche Coder efficacement, bonnes pratiques et erreurs à éviter. Évalué à 2.

    Mais dire qu'en pratique on ne pratique pas la récursion, c'est un peu osé.

    Certes ; mais c’est beaucoup plus rare. Il serait intéressant de savoir combien il y a de fonction récursive dans le noyau Linux. J’avoue en avoir aucune idée, mais à mon avis il n’y en a pas beaucoup.

    J'aimerais bien savoir combien d'OS sont écrits dans des langages fonctionnels.

  • [^] # Re: C'est pourtant évident.

    Posté par  . En réponse à la dépêche Coder efficacement, bonnes pratiques et erreurs à éviter. Évalué à 2.

    Non ce n’est pas valide !

    Et moi je te dis que si. Il y aura une optimisation pour transformer la récursion en boucle (ou pas), mais ce code est du C parfaitement valide. Il n'y a pas de discussion possible ici : il est écrit en C, qui autorise la récursion.

    Et ce code à clairement un fuite mémoire sans l’implémentation de l’optimisation de la récursion terminale (ce qui est un bug).

    Non. Car je le répète, le C n'impose pas l'utilisation d'une pile. La fonction loop ci-dessus ne fait absolument aucune allocation — outre le fait qu'effectivement, il faut trouver un moyen de garder les pointeurs msg successifs en mémoire, mais ce n'est pas un problème du langage, car encore une fois, il ne suppose rien concernant l'organisation de la mémoire physique de la machine (ça se trouve, tout est alloué sur le tas, ou bien le PC a une pile de taille infinie, etc.). De même qu'écrire ceci est valide :

    while (1) 
        ; // nothing

    La transformation d’appel récursif vers une boucle est une optimisation dans le cas des langages impératifs (ce n’est pas dans la norme) mais une fonctionnalité dans les langages fonctionnelles (garantie par la norme). En théorie ça pourrait être différent, mais en pratique c’est ce que l’on observe.

    Uniquement dans les langages fonctionnels purs, alors. Car j'ai déjà donné l'exemple de Common LISP qui n'a aucune garantie dans la norme à ce sujet. Ensuite, comme tu le dis, il s'agit d'une optimisation pour les langages impératifs, ce qui indique bien que le programme est parfaitement valide lorsqu'il est exécuté sur une machine abstraite (et c'est tout ce qu'on demande à une norme, qui ne peut prévoir tous les progrès architecturaux à venir).

    Cette différence de statut (fonctionnalité/optimisation) n’est pas un simple détail ! Elle change la façon dont on programme. En pratique personne ne programme en récursif en dehors des langages fonctionnels (en tout cas c’est minoritaire), ce n’est pas du tout l’esprit.

    Oui, évidemment, on utilise beaucoup de constructions itératives dans les langages impératifs. Mais dire qu'en pratique on ne pratique pas la récursion, c'est un peu osé.

    L’optimisation de la récursion terminale fait partie de l’esprit de la programmation fonctionnel, mais pas de celui de la programmation impérative.

    Transformer un appel récursif terminal en boucle est une obligation pour un langage fonctionnel pur (i.e., qui n'accepte pas les boucles), pour les raisons pratiques que tu as évoquées. Un langage impératif a déjà une façon d'exprimer le résultat final à travers une boucle directement. Dans les deux cas, la transformation d'une récursion terminale vers une boucle est un cas qui n'est pas réservé à un style de programmation : impératif ou fonctionnel, à partir du moment où tu acceptes qu'une fonction peut être récursive, alors la spécification de ton programme dit que toute récursion est légale (je grossis le trait mais j'espère que tu comprends ce que je veux dire). La transformation de RT → boucle est possible dès lors que la forme est respectée, et ceci est indépendant du type de langage. Tu peux tenter de nuancer en disant qu'en C ou C++ ce n'est qu'une optimisation, mais la vérité, c'est qu'il existe énormément d'algorithmes qui sont effectivement exprimés sous forme récursive, et qui, pour des raisons de performance, vont être modifiés jusqu'à atteindre une forme récursive terminale. Ensuite on pourrait bien entendu aller à l'étape suivante « directement » (transformer le tout en boucle), mais comme la plupart des compilateurs savent faire les choses correctement, pourquoi s'emmerder ?

  • [^] # Re: C'est pourtant évident.

    Posté par  . En réponse à la dépêche Coder efficacement, bonnes pratiques et erreurs à éviter. Évalué à 3.

    J'oubliais de répondre à ceci :

    Le problème c’est que ce n’ai pas une question d’optimisation mais de validité.

    Le code que tu proposes, que je traduis en C ainsi :

    void 
    loop(void)
    {
        char* msg = receive_msg();
        puts(msg);
        loop();
    }

    … est récursif terminal, et est un programme valide en C. Comme je le disais précédemment, le C n'a pas de notion de pile (même si c'était je pense implicite dans les specs avant la normalisation du langage). Donc il n'y a pas de notion de dépassement de pile en termes de langage. Évidemment, en termes d'implémentation, le risque est grand.

    Ceci étant dit, un langage comme Perl est capable d'effectuer des récursions bien plus profondes que ce qu'une simple pile UNIX propose, ce qui implique que la VM de Perl et le langage lui-même implémentent un truc permettre que cela arrive…

  • [^] # Re: C'est pourtant évident.

    Posté par  . En réponse à la dépêche Coder efficacement, bonnes pratiques et erreurs à éviter. Évalué à 3.

    Ce n'est pas garanti en C, mais en même temps, le C ne définit pas une notion de pile. Il existe de vieilles implémentations de C89 qui n'utilisent pas la pile pour les appels de fonction, sur des architectures un peu exotiques.

    Mais tu mélanges deux choses :

    1. La transformation de constructions récursives terminales en boucles, qui n'est pas une exclusivité des langages fonctionnels (c'est une transformation classique, appliquée par la plupart des compilateurs optimisants depuis 15 ans);
    2. La garantie dans le langage qu'une construction récursive terminale sera transformée en boucle.

    Que Erlang te donne une garantie sur la transformation des tail calls, c'est très bien. Ça n'indique pas pour autant que la transformation récursion terminale → boucle est toujours effectuée dans les langages fonctionnels. Par exemple, pour Common LISP, presque tous les compilateurs sont capables de le faire, mais tous ne le font pas pour autant. Donc pour le deuxième point, c'est évidemment un plus si le langage garantit la transformation automatique, mais ça n'est (encore une fois) pas quelque chose de fondamentalement lié au côté fonctionnel ou impératif d'un langage. C'est juste que dans un langage fonctionnel pur, il n'y a pas de constructions de boucles, et donc si tu veux pouvoir garantir une certaine performance, il faut implémenter les tail calls sous forme de boucle.

  • [^] # Re: C'est pourtant évident.

    Posté par  . En réponse à la dépêche Coder efficacement, bonnes pratiques et erreurs à éviter. Évalué à 2.

    OoOoOOoh, je ne connaissais pas. Merci. :)

  • [^] # Re: C'est pourtant évident.

    Posté par  . En réponse à la dépêche Coder efficacement, bonnes pratiques et erreurs à éviter. Évalué à 7.

    C'est faux. GCC le fait, ICC le fait

    Le C peut le faire ?? Je me coucherai moins bête ce soir !
    C’est imprécis mais c’est pas faux.

    Non, ce n'est pas imprécis. tu dis que les langages impératifs ne permettent pas l'optimisation des fonctions récursives terminales. C'est factuellement faux, car comme le dit Turbo, l'important est de savoir si la forme est récursive « simple » ou bien récursive terminale. Et ceci est indépendant de la nature du langage (fonctionnel, impératif, etc.). En fait, les algorithmes qui transforment une récursion terminale en boucle sont connus depuis un moment, et il y a une équivalence automatique. Donc les compilateurs pour langages comme OCaml (ou F#), ou comme Scala, ou même Common LISP, qui sont tous multi-paradigmes, pourraient tous implémenter la récursion terminale en théorie. Ensuite, pour prendre l'exemple de Scala/Clojure/Java, il n'y a rien, ni dans la JVM, ni dans les langages eux-mêmes, qui empêche la transformation d'une fonction récursive terminale du type :

    let fact n = 
        let rec factorial n acc = match n with
            | 0 | 1 -> acc
            | _ -> factorial (n-1) (n*acc)
    
        factorial n 1

    … en un code bas-niveau du genre (en pseudo-C) :

    int 
    fact(int n)
    {
        int acc = 1;
    FACTORIAL:
        if (n == 0 || n == 1)
            return acc;
        acc *= n;
        n   -= 1;
        goto FACTORIAL;
    }

    Étant donné que la JVM a une instruction goto pour le bytecode, transformer une fonction récursive terminale en boucle à l'aide d'un goto est trivial. Par contre il est possible que la machine à pile qui est à la base de la JVM ajoute des contraintes sur la façon de générer le code (je ne suis pas du tout expert ni même connaisseur du fonctionnement de la JVM).

    Concernant Python, Ruby, etc., il y a plein d'optimisations qui ne sont jamais faites dans ces langages, dues à la nature dynamique de ceux-ci (dynamique en termes de types, mais aussi pour la génération de code elle-même). Un truc qui serait optimisé dans beaucoup de cas en C+libC serait par exemple¹ :

    /* Terrible, terrible way of copying strings. Assumes NULL-terminated strings, makes no checks, etc. */
    char* bad_strcpy(char *dst, const char *src)
    {
        for (size_t i = 0; i < strlen(src); ++i) 
            dst[i] = src[i];
    
        return dst;
    }

    Dans cet exemple, le compilateur C a le droit de transformer le code ainsi :

    /* Terrible, terrible way of copying strings. Assumes NULL-terminated strings, makes no checks, etc. */
    char* bad_strcpy(char *dst, const char *src)
    {
        size_t src_len = strlen(src);
        for (size_t i = 0; i < src_len; ++i) 
            dst[i] = src[i];
    
        return dst;
    }

    En Perl/Ruby/Python, de par la nature dynamique de ces langages, il faut nécessairement effectuer cette optimisation à la main. Maintenant, voilà le côté rigolo de ces langages : je connais mal Python, mais j'ai pas mal programmé avec Perl, et un peu avec Ruby. De ce que je vois, aucun de ces langages n'est purement impératif : ils ont tous des constructions fonctionnelles (par exemple : map et grep en Perl). Ils proposent des trucs genre les fermetures (closures en Anglais), qui sont apparues avec les premiers langages fonctionnels. De même, des langages impératifs destinés à la programmation parallèle, comme Habanero (Habanero Java, Habanero C, qui sont des dérivés sur langage X10) proposent des trucs qu'on trouve généralement dans les langages fonctionnels, comme le principe de future — et qui se trouve désormais aussi dans le standard de C++11. Tiens, en parlant de C++, la méta-programmation par templates se fait en effectuant de la programmation fonctionnelle (tout est « write once », tout est valeur).

    Enfin, j'ai une dernière remarque : les ordinateurs qui suivent le modèle d'exécution de von Neumann² sont par définition des machines qui fonctionnent selon un principe impératif/itératif : il y a un compteur de programme (PC), qui est incrémenté à chaque cycle (ou bien, en cas de branchement, à qui on affecte une nouvelle adresse pour la prochaine instruction). Il n'y a aucune trace de comportement fonctionnel. Tout le génie de ceux qui proposent des langages comme les dialectes de LISP, ML, Haskell, etc., est justement de proposer une façon d'exprimer les programmes sous une forme de bien plus haut niveau, non-impérative (et donc, permettant au programmeur de ne pas penser en termes de ce qu'attend la machine), mais de malgré tout réussir à convertir ces programmes à nouveau sous une forme impérative compréhensible par une machine de von Neumann de façon efficace.

    Backus (le papa de Fortran) a d'ailleurs expliqué qu'il avait commis une grande erreur en créant Fortran, et que le futur devrait se construire sur la programmation fonctionnelle (le lien que je donne est son discours/sa présentation donné lors de son acceptation pour le prix Turing).

    [1] Comme la libC est standard, elle est du coup « magique ». Le compilateur a le droit de faire des trucs étranges avec tant que ça respecte la sémantique des fonctions standard.
    [2] Soit 99% des ordinateurs de la planète à travers les âges. Il y a des machines différentes, qui n'utilisent pas du tout les concepts de compteur de programme, mais elles ont malheureusement toutes échoué à dépasser les autres en termes de performances.

  • [^] # Re: C'est pourtant évident.

    Posté par  . En réponse à la dépêche Coder efficacement, bonnes pratiques et erreurs à éviter. Évalué à 5.

    Donc pour résumé, la récursion est optimisés (dans certain cas) dans les langages fonctionnelles et pas chez les langages impératifs.

    C'est faux. GCC le fait, ICC le fait, MS-VC++ aussi. Si tu mets ta fonction sous forme récursive terminale, n'importe quel compilateur optimisant un minimum moderne sait transformer la récursion terminale en boucle. En fait, GCC sait faire de l'optimisation de récursion terminale depuis au moins la version 2.95 (pour rappel, on en est à GCC v4.8).

    Encore pire, il existe tout un tas de cas où GCC va faire du « pattern matching » et reconnaître une forme récursive d'un algo, ou en tout cas un idiome récursif « facile » à transformer en récursion terminale, et du coup effectuer la transformation…

    Bref, à moins qu'un compilateur pour langage fonctionnel ait des mécanismes permettant de plus facilement convertir une récursion « normale » en récursion terminale¹, il n'y a absolument aucun avantage en termes d'optimisation à choisir un langage fonctionnel plutôt qu'impératif.

    J'aime bien les langages fonctionnels, mais une fois que n'importe quel programme, écrit dans n'importe quel langage, a été correctement analysé (analyse lexicale, grammaticale, sémantique, blah), on se retrouve avec un arbre de syntaxe abstrait, c'est-à-dire une représentation intermédiaire qui permet de « visualiser » un programme sous forme de graphe de dépendance (de données, de contrôle, etc.), et autres machins. À partir de là, on peut commencer à effectuer des transformations sur le programme, à « marquer » les nœuds qui pourraient être groupés avec d'autres, ou même supprimés, etc.

    Par contre, là où les langages fonctionnels ont tendance à briller (je trouve), c'est dans la façon dont ils manipulent plus souvent des « valeurs » que des variables. En gros, souvent les langages fonctionnels proposent un mode qui tient plutôt du « write-once » par défaut, qu'on peut explicitement invalider si on veut des effets de bord, alors que les langages impératifs ont tendance à autoriser les variables à être modifiables par défaut, et il faut ensuite mener une guerre méthodologique pour placer autant de constantes que possibles pour se prémunir contre les effets de bord non désirés.

    [1] Et pour le coup je ne vois pas du tout comment ce serait possible…

  • [^] # Re: Ca traduit bien un état d'esprit de la part des développeurs de systemd

    Posté par  . En réponse au journal Systemd vs Linux, quand l'intransigeance d'un développeur tourne au ridicule.... Évalué à 6.

    Quand un pourcentage significatif de gens gueulera à cause de ça, Microsoft reconsidèrera sa position. Pour le moment, ne sont embêtés que les gens avec un linux qui en plus utilisent un Windows.

    C'est d'ailleurs ce qu'a fait Apple pour BootCamp etc. : un certain nombre de personnes voulaient un Windows parce que c'était pour le boulot, parce que y'a tel ou tel jeu qui ne marche pas sous MacOS X, etc.

  • [^] # Re: Et le programme ?

    Posté par  . En réponse au journal Le Parti Pirate cherche 5 femmes pour les Européennes avant le 21 avril. Évalué à 3.

    Oui enfin, le parti Republicain US, il englobe tout du centre-droit au type qui ferait pâlir le FN dans certains cas.

  • [^] # Re: Au nom de l'égalité…

    Posté par  . En réponse au journal Le Parti Pirate cherche 5 femmes pour les Européennes avant le 21 avril. Évalué à 6.

    Je suis d'accord avec toi sur le fond, mais je rajouterais une nuance vis à vis de cette partie de ton post :

    Ouai, on peut choisir des gens compétents. J'espère que c'est ce qu'ils ont fait avant. Des femmes (comme les hommes) compétents en politique, ce ne sont généralement pas des gens qui attendent chez eux qu'on vienne les chercher pour leur apporter la révélation sur leur talent et leur motivation.

    Tout un tas de personnes (pas spécialement des femmes, mais aussi des gens qui n'ont pas le même vocabulaire, ou etc.) vont être considérées/vues comme "incompétentes" non pas parce que c'est vrai, mais parce qu'elles ont une forme de pensée différente, qu'elles considèrent un problème d'un point de vue complètement différent, etc.

    Je vais donner un exemple qui sort totalement du thème de ce fil de discussion pour illustrer mon propos. Dans freakonomics, les auteurs racontent comment aux USA dans les années 1990, on observait une montée de la délinquance juvénile, et que tout le monde s'attendait à ce qu'elle explose après 1995, au vu des tendances. Et puis, "plus rien". On a attribué ce résultat à la politique de Juliani (le nouveau maire de l'époque). Les auteurs disent que, si une partie peut effectivement lui être attribué (il a augmenté le nombre de policier dans certains quartiers par exemple), cela ne suffit pas à tout expliquer car le problème de délinquance était présent un peu partout dans les villes américaines. Puis, les auteurs proposent leur explication: 1995 correspond peu ou prou au 20e anniversaire de la loi sur la légalisation de l'avortement aux USA, et émettent l'hypothèse que grâce à cette dernière, les enfants nés après ~1975 étaient déjà bien plus désirés (ils pouvaient toujours être le résultat d'accidents, mais les parents qui décidaient de garder les enfants étaient en grande majorité capables de subvenir aux besoins de leurs enfants—les autres avortaient).

    Cette hypothèse est contestable (et contestée), mais beaucoup de gens l'ont considérée comme non seulement intéressante, mais convaincante.

    Pour revenir à la compétence des candidats, on confond souvent forme et fond : quelqu'un qui ne maîtrise pas aussi bien le vocabulaire d'un sujet sera vu avec une certaine condescendance par certains experts, qui eux, ont passé leurs 5 années d'études à travailler sur le sujet.

    De plus, au-delà des apparences, il y a le problème du point de vue énoncé plus haut : parce que quelqu'un va poser une question avec un angle surprenant (et parfois peut-être saugrenu), on va le moquer, ne pas l'écouter jusqu'au bout, etc. Il ne faut pas sous-estimer la stupidité des individus dans de grands groupes.

    Bref, on retombe dans les travers des Sciences Po'/ENA, etc., mais aussi du fait que beaucoup de gens qui veulent pouvoir rester au niveau auquel ils sont arrivés avec ou sans cette éducation, vont devoir se conformer au moule sous peine de se faire bouler, invectiver, moquer, etc. J'ai en tete deux événements qui se sont passés ca ~5-6 ans d'intervalle :

    1. Lorsque Royale[1] se présente aux primaires, la réaction de Fabius a été : "Mais qui va faire la cuisine ?" (ho ho ho, quelle bonne blague, roooh mais c'est de l'humour, ça va quoiii !)
    2. Lorsque Duflot est venue s'exprimer à l'Assemblée Nationale, on l'a sifflée, fait des commentaires déplacés, etc., parce qu'elle avait osé venir dans une robe vaguement d'été/printemps plutôt qu'un tailleur strict.

    Impossible de croire que les gens qui ont eu ces réactions ont du respect pour l'opinion de celles qu'ils moquaient (ils étaient nombreux dans le cas de Duflot, et sans doute pas beaucoup moins nombreux, même si moins vocaux dans le cas de Royale).

    [1] Qu'elle fut compétente ou pas n'a rien à voir avec le sujet. Elle est un cadre du PS, elle a donc toute légitimité pour se présenter. D'une certaine manière, elle avait déjà "fait ses preuves".

  • [^] # Re: Debian compromis par la NSA ?

    Posté par  . En réponse à la dépêche Nouvelle vulnérabilité dans l’implémentation OpenSSL. Évalué à 6.

    certains américains et en particulier dans les sphères politiques veulent mettre des limites sur la capacités de la NSA d'espionner les américains des USA le reste ils ne veulent surtout pas changer.

    Ça va même plus loin que ça. Les membres du congres US ont commencé à s’inquiéter quand ils ont appris que leurs conversations (via email ou téléphone) étaient susceptibles d’être espionnées. Avant ça, ils n'en avaient rien à foutre, citoyens US ou pas.

  • [^] # Re: Remplacer l'assembleur par Ada ou Rust ?

    Posté par  . En réponse à la dépêche Nouvelle vulnérabilité dans l’implémentation OpenSSL. Évalué à 5.

    Pour faire de la crypto en labo non, mais pour faire le site de vente en ligne ou d'une banque, je crains que si.

    Oui alors euh, certains des gens qui faisaient de la crypto dans mon labo avaient des petites phrases du genre « C est trop haut-niveau, c'est chiant, quand j'ai un overflow (que je pourrais exploiter) il me le dit pas ! ».

    Sinon, si pas mal de mes collègues cryptologues avaient effectivement commencé à bosser sur des softs de type magma pour représenter leurs courbes elliptiques etc., une fois que leurs protocoles étaient au point et testés, ils ont quand même eu à aller recoder leurs algos en C avec libgmp (à l'époque je crois que c'est ce qu'ils utilisaient). Sinon, il aurait été difficile de déterminer en combien de temps leurs attaques allaient réellement porter leurs fruits, etc. Et oui, au bout d'un moment, il y avait aussi du SSE voire du AVX qui entrait dans la danse…

  • [^] # Re: Une nouvelle pour l'auteur du journal

    Posté par  . En réponse au journal So, you wanna be a sysadmin ? (Trolldi inside). Évalué à 3.

    À toi de rendre ton environnement idiot proof.

    Je vais citer Rick Cook:

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.

    Même chose avec les utilisateurs/sysadmin. Il y aura toujours un « meilleur » idiot. Ça ne justifie pas qu'on crache sur les utilisateurs pour autant hein. Juste que admin système ne veut pas dire uniquement jouer avec les machines, mais aussi joue… Euh, interagir avec les utilisateurs. :-)

  • [^] # Re: Ca traduit bien un état d'esprit de la part des développeurs de systemd

    Posté par  . En réponse au journal Systemd vs Linux, quand l'intransigeance d'un développeur tourne au ridicule.... Évalué à 2.

    Indéfini (Undefined Behavior) ou implementation defined ?

  • [^] # Re: Ca traduit bien un état d'esprit de la part des développeurs de systemd

    Posté par  . En réponse au journal Systemd vs Linux, quand l'intransigeance d'un développeur tourne au ridicule.... Évalué à 2.

    Ah oui, j'oubliais : je parlais de la dernière fonction (je n'avais pas testé les autres).

  • [^] # Re: Ca traduit bien un état d'esprit de la part des développeurs de systemd

    Posté par  . En réponse au journal Systemd vs Linux, quand l'intransigeance d'un développeur tourne au ridicule.... Évalué à 2.

    Si, complètement. clang et icc me le disent sans activer de warnings. gcc a besoin de -Wall.

  • [^] # Re: Ca traduit bien un état d'esprit de la part des développeurs de systemd

    Posté par  . En réponse au journal Systemd vs Linux, quand l'intransigeance d'un développeur tourne au ridicule.... Évalué à 2.

    Concernant la fonction et le commentaire, comme p1 et p2 sont de type const void*, écrire *p1 et *p2 n'a pas réellement de sens. Si la fonction de comparaison avait du renvoyer "juste" les valeurs -1, 0, et 1, alors il aurait même été complètement redondant pour les premières versions que je proposais de mon code. Le "truc" de ces fonctions de comparaisons est que la seule valeur "précise" à laquelle on s’intéresse est celle d’égalité (0). Dans la vraie vie, mon commentaire aurait sans doute été plus long, pour expliquer les entrées, vers quel type elles allaient être converties, etc. Là, c’était juste pour insister sur le fait que d'autres valeurs de retour, positives ou négatives et autres que -1 ou 1, étaient valides.

    En règle générale, lorsque je compile du C avec gcc, je le fais avec -Wall -Wextra et même parfois (souvent) -pedantic. Je ne sais pas quelle est la règle officielle dans la norme, mais je sais que pour main, beaucoup (la plupart ?) des compilateurs retournent implicitement 0 si aucun return n'est inséré. clang m'indique que la fonction ne renvoie rien malgré son type de retour, et ceci sans warnings.icc tout pareil. Mea culpa, je n'avais pas testé mes codes avant de les poster ici.

    Concernant tes autres questions (pourquoi passer des const void* plutôt que directement les int par valeur, etc.), zul et fearan ont parfaitement répondu : il s'agit d'un comparateur destiné à être passé à une fonction "générique". Seul void* correspond au type "générique" (sans passer par des macros).

  • [^] # Re: Ca traduit bien un état d'esprit de la part des développeurs de systemd

    Posté par  . En réponse au journal Systemd vs Linux, quand l'intransigeance d'un développeur tourne au ridicule.... Évalué à 2.

    C'est exactement qsort que je visais (j'ai eu le cas qui se posait récemment).