Alfred, réveille-toi, ils sont devenus fous !

11.10.13 | par Le Grincheux | Catégories: Mauvaise humeur

Voilà, c'est fait. Le prix Nobel de la paix bient d'être attribué à l'Organisation pour l'Interdiction des Armes Chimiques. D'un autre côté, il n'a pas été décerné à Vladimir Poutine, c'est déjà ça de gagné.

Pourtant, décerner le prix Nobel de la Paix à Malala Yousafzaï (16 ans), cela aurait eu une certaine allure, elle qui a payé, et lourdement payé dans sa chair son combat contre l'obscurantisme des fous de dieu.

Au lieu de cela, le comité Nobel a fait une fois de plus dans la politique de bas étage.

Je ne suis pas convaincu que donner ce Nobel a Malala l'aurait aidé dans sa lutte ouverte. Cela aurait été pour elle un risque supplémentaire, peut-être inutile. Mais au moins, cela aurait donné un signal fort en provenance de la communauté internationale. Au lieu de cela, il est attribué à un sombre organisme destiné à lutter contre les armes chimiques dans un pays, la Syrie, qui dit ouvertement ne pas en posséder. Nous allons en voir l'inefficacité dans les mois qui viennent.

C'est moralement discutable et Malala peut se consoler avec le Prix Sakharov pour la liberté de l'esprit du Parlement européen qui lui a été décerné le 10 octobre 2013.

Le prix Nobel de la Paix est devenu le pendant de la Légion d'Honneur, une distinction donnée à n'importe qui pour n'importe quoi. Souvenez-vous de l'inventeur du micro-crédit qui a été distingué après avoir fait fortune en prêtant des sommes minimes à des taux proches de l'usure. Il a peut-être aidé des foules immenses, pris des risques énormes, mais de là à en faire un philanthrope, il y a une marge.

 

Oracle, ô désespoir

11.10.13 | par Le Grincheux | Catégories: Mauvaise humeur, Je hais l'informatique, Je hais les financiers

Je ne me suis converti aux serveurs X86 que très récemment et, je dois dire, par défaut, faute de combattants. En effet, ma conversion n'a pas été dictée par une hausse sensible de la qualité des serveurs de type PC, mais par la baisse assez nette de celle des architectures concurrentes. Pourquoi aujourd'hui payer le prix fort d'une architecture bien conçue alors que la qualité n'est plus au rendez-vous ?

Pourtant, j'étais l'un des derniers mohicans.

Depuis le milieu des années 1980, j'ai eu successivement des S.M.T. Goupil (G3/6809 avec disques durs ST506), des IBM PS/2, du matériel Digital Equipment Corporation sous la forme de PDP-11, VAX et Alpha et une foultitude de matériel Sun Microsystems, exclusivement d'architecture Sparc.

Fig. 1 : logo permettant de reconnaître un matériel informatique peut-être de qualité

Parmi le matériel Sun, j'ai eu l'occasion de voir passer chez moi une partie de la série sun4c (SparcStation 2, SparcStation IPC, SparcStation IPX avec Weitek PowerUP), les plus beaux représentants de la famille sun4m (SparcStation 5 et 20 avec SuperSparc II et HyperSparc), le serveur raté sun4d 600M, quelques sun4u (Ultra 1E, 2E, 5, 60, 80, 420R, Blade 2000) et des sun4v (T1000 et T2000). J'ai donc une vue à peu près représentative du matériel, de son évolution et de ses points faibles.

Les SparcStations étaient des machines très onéreuses. Mais je dois dire que toutes mes anciennes sun4c et sun4m fonctionnent toujours. Même une SparcStation 20 allant sur ses vingt ans et pourtant stressée puisqu'elle embarque 448Mo de mémoire, une VRAM de 8Mo, quatre processeurs ROSS HyperSparc à 200MHz, une carte SCSI additionnelle, quatre ports 100BaseTX supplémentaires et deux disques U320 SCSI de 300Go, tout cela avec son alimentation d'origine fournissant à peine plus de 100W mais avec quelques ventilateurs supplémentaires. Un processeur ROSS, ça chauffe un petit peu, alors des modules doubles, même en double largeur, ça chauffe beaucoup.

Les Ultra 1E et 2E sont d'assez bonne facture et ne posent pas de problèmes particuliers une fois oublié le mauvais vieillissement du ventilateur du processeur UltraSPARC 1 de l'U1E. En revanche, il y a eu une certaine dégradation lors du passage des machines Sbus/UPA aux machines PCI/UPA. Et un naufrage total lors du passage du PCI/UPA vers le PCI-X/PCI-E. Oracle n'a plus eu qu'à se baisser pour ramasser Sun Microsystems.

L'Ultra 5 est la première machine à problèmes. Le contrôleur de disque dur, un vulgaire contrôleur IDE, est vérolé jusqu'à la moelle. Les barrettes mémoire n'arrêtent pas de lâcher les unes après les autres. Heureusement, ce sont des barrettes ECC, donc le système prévient gentiment qu'elles sont en train de mourir avant qu'il ne soit trop tard. Enfin, il prévient souvent, presque toujours, mais cela n'empêche pas les mauvaises surprises. En dehors du caractère ECC, ces barrettes n'ont rien de plus qu'une vulgaire barrette mémoire d'un PC de bureau. Chose amusante, elles vieillissent bien plus mal que des barrettes no name de PC fabriquées en Chine sans aucun contrôle qualité. Faire de telles économies de bouts de chandelle au vu du prix d'achat d'une Ultra 5, c'est tout de même se moquer du monde voire prendre ses clients pour des imbéciles. À partir de ce moment, la part des machines Sun a commencé à s'écrouler. Le fait qu'il était possible d'utiliser Solaris sur des PC standard n'a pas aidé non plus.

Les U60, U80 et U420 étaient plus fiables que les U5. Enfin, si l'on peut dire. Sur les U60, un peu moins sur les U80, les alimentations n'arrêtent pas de claquer les unes après les autres. Heureusement, elles meurent sans injecter de haute tension sur l'électronique. Elles meurent parce qu'un condensateur travaille trop près de sa tension maximale, avec une ondulation trop forte et donc chauffe, vieillissant prématurément. Elles meurent aussi parce que les diodes Schottky d'entrée sont un peu faibles. Économiser trois francs six sous sur des machines qui valaient plusieurs dizaines de milliers de francs est mesquin. Les U80 provoquent elles-mêmes des erreurs de correction de la mémoire dès qu'elles contiennent 4Go de mémoire, ce que ne font pas les U420 utilisant pourtant la même carte-mère et les mêmes mémoires. Allez comprendre.

Et que dire des Blade 2000 ? Les Blade 2000 sont sensibles. Très sensibles. Les capteurs de température des processeurs renvoient par moment des valeurs aberrantes forçant la machine à s'arrêter brutalement car elle se met en protection. En mettant à jour l'openprom, on arrive à corriger le problème. Encore faut-il trouver la bonne version de l'openprom et avoir un contrat chez Sun pour pouvoir télécharger le patch. Mais cela ne règle pas le problème de la mémoire. Souvenez-vous. Nous étions le 1er août 2010. Une éruption solaire d'intensité C3 est dirigée vers la Terre, conduisant les 3 et 4 août 2010 à des tempêtes magnétiques avec force aurores boréales. Le samedi 7 août, les champs magnétiques autour de la tache 1093 produisent une éruption. Les sondes de la NASA photographient l’explosion qui génère une grosse protubérance de classe M1 et précipite une éjection de masse coronale (CME) dans l’espace — qui apparemment évite de justesse le plan de la Terre, nous sommes chanceux. L’explosion provoquent aussi des bruits de glissades dans les hauts parleurs de certaines radios ondes courtes. Et les Blade 2000 tombent comme des mouches avec des erreurs de mémoire du type :

Cheetah error trap taken
afsr[0000004000000037] afar[0000000034ae79c0]
TL1(0) TPC[4f2808] TNPC[4f280c] O7[4f27ec]
TSTATE[4411001607] M_SYND(0), E_SYND(37)
Highest priority error (0000004000000000)
"HW corrected E-cache ECC error for writeback"
ERROR(1): AFAR E-syndrome [J0203, pin 135]
ERROR(1): D-cache idx[0] tag[0000000000000000]
utag[0000000000000000] stag[0000000000000000]
D-cache data0[0000000000000000] data1[0000000000000000]
data2[0000000000000000] data3[0000000000000000]
I-cache idx[0] tag[0000000000000000]
utag[0000000000000000] stag[0000000000000000]
u[0000000000000000] l[0000000000000000]
I-cache INSN0[0000000000000000] INSN1[0000000000000000]
INSN2[0000000000000000] INSN3[0000000000000000]
I-cache INSN4[0000000000000000] INSN5[0000000000000000]
INSN6[0000000000000000] INSN7[0000000000000000]
E-cache idx[34ae79c0] tag[0000000000000045]
E-cache data0[0000000000000000] data1[0000000000000000]
data2[0000000000000000] data3[0000008000000000]

Plusieurs barrettes mémoire à changer pour que tout redevienne fonctionnel.

Il y a quelques mois, j'ai eu les mêmes problèmes sur des T1000. Barrettes mémoire parties en vacances pour des durées indéterminées. Pourtant, ces machines sont branchées sur un courant secouru parfaitement ondulé. Et cette nuit, rebelote :

SC Alert: MB/CMP0/CH3/R1/D0 deemed faulty and disabled
SC Alert: MB/CMP0/CH3/R1/D1 deemed faulty and disabled
ERROR: The following devices are disabled:
MB/CMP0/CH3/R1/D0 MB/CMP0/CH3/R1/D1

Ce n'est pas beau. J'ai réussi à faire redémarrer ce serveur à distance en désactivant deux barrettes mémoire sur les huit. Sur une machine coûtant la bagatelle de plus de 15000€ HT, c'est navrant.

 

L'heure des choix

09.10.13 | par Le Grincheux | Catégories: Monde de merde, Je hais les politiciens

J'ai rencontré un syndicaliste. Je devrais écrire un syndicaliste intelligent, il en existe tout de même quelques uns, luttant pour le bien du pays et non pour son confort personnel puisqu'il distribuait des tracts pour une mobilisation constructive et la mise à plat des trente-cinq régimes de retraite français alors que, dépendant d'un régime spécial, il avait tout à y perdre.

Je lui annonce que profession libérale, je n'entre pas dans la catégorie de travailleurs dépendant de son syndicat. De là part une discussion que je qualifierais avec le recul d'instructive et de pathétique.

Reprenons les faits. Un syndicaliste vient me voir et ne me traite pas de psychopathe — sic le dernier de la CGT que j'ai pourtant aimablement reçu dans mon bureau une fois qu'il en avait forcé la porte —, pire, écoute mes problèmes et me signale que sa sœur était dans la même situation que la mienne.

Ce syndicaliste, de statut cadre, a une sœur d'une quarantaine d'années qui a fait des études pour être orthophoniste. Travaillant du lundi matin 9h00 au samedi soir, sans jour de congé, elle gagnait il y a deux ans 2000 € nets à la fin du mois. L'an passé, elle ne gagnait plus à volume de clientèle par ailleurs égal que 500 € nets mensuels et, cette année, il m'a dit devoir l'aider à la fin du mois car elle n'arrivait plus à nourrir sa famille. Nous parlons bien entendu d'un cabinet qui fonctionne normalement, depuis plus de dix ans, pas d'un nouveau cabinet qui n'a aucune clientèle. Le choix pour cette femme est de continuer le métier pour lequel elle a sacrifié des années d'étude ou d'en changer pour réussir à vivre.

J'avais l'impression d'être un peu moins seul. Je n'irais pas jusqu'à dire que cela fait du bien, mais ne pas être seul dans ce genre de situation démontre au moins que je ne me raconte pas des histoires pour me rassurer.

En effet, je suis confronté au même problème. L'an passé, j'arrivais à un solde positif tous les mois de pas loin de 2000 €, solde positif que je réinvestissais immédiatement car je ne peux compter sur personne pour avoir une retraite si un jour j'y arrive. Cette année, le solde n'est plus lors des bons mois que de 500 € et je sais déjà que l'an prochain, ce solde sera au mieux nul. Je dis au mieux parce que dans la pire des situations, il pourrait être négatif de 500 €. Cette modification n'est pas due à une baisse de revenu mais à la simple augmentation de mes impôts et charges.

En mettant à plat mon budget mensuel avec mon expert-comptable, nous sommes arrivés à la conclusion aberrante suivante : je dégagerais plus d'argent à la fin du mois en mettant mon appartement et mon garage parisiens en location et en allant prendre n'importe quel travail d'employé de base en Alsace ou en Corrèze payé 1500 € nets mensuels. En plus, je ne travaillerais plus que trente-cinq heures, aurait des heures supplémentaires, cinq semaines de congés payés et la sécurité sociale. Je n'ai donc aucun intérêt à continuer à faire mon métier.

Il y a juste un problème. J'ai sacrifié dix ans de ma vie après le baccalauréat pour faire des études me permettant de ne pas vivre correctement des fruits de mon travail (deux ans de classes préparatoires, un diplôme d'ingénieur en électronique et traitement du signal, un mastère de communications numériques et une thèse de doctorat en traitement du signal et métrologie) et cela m'ennuierait légèrement de les oublier pour aller faire chef de rayon au supermarché du coin. Je n'ai pas passé dix ans de ma vie à vivre comme un moine pour gâcher cela dans un métier alimentaire pour de simples raisons financières.

Actuellement, je suis démarché par un cabinet de recrutement suisse. Sachant que j'arrive à peine à vivre en France du fruit de mon travail, que croyez-vous que je vais faire ?

À votre avis, à long terme et sachant que je ne suis pas le seul dans ce cas, quels seront les vrais perdants ?

 

Dépression

09.10.13 | par Le Grincheux | Catégories: Je hais les financiers, Je hais les politiciens

Nul n'est prophète en son pays. Et surtout, nul ne doit avoir raison trop tôt. Au printemps 2007, j'écrivai un article dans une revue dans lequel je signalais que la période dans laquelle nous étions en train d'entrer ferait passer la grande dépression de 1929 pour une aimable promenade de santé. J'y indiquai aussi que cela ne serait pas une crise mais une situation longue de laquelle nous ne nous sortirons qu'après un très long purgatoire.

Nous étions un an avant le 15 septembre 2008, chute de Lehman Brothers.

Notez bien que je ne tire aucune fierté ni aucune gloire de l'avoir écrit. Je pense même que nous aurions pu nous affranchir de la période actuelle. Il aurait suffit de prendre les mesures qui s'imposaient et que le gouvernement aurait encore pu prendre jusqu'en 2009.

Pourtant, aujourd'hui, soit cinq ans après la déflagration due à la faillite de Lehman, force est de constater que rien n'a réellement changé. Mais comment pourrait-il en être autrement ?

En effet, les errements de tous les gouvernements des pays dits développés depuis une bonne trentaine d'années ne permettent pas de sortir de la situation actuelle sans pleurs ni grincements de dents. Rares sont les pays qui ne sont pas endettés à outrance à force d'essayer de faire perdurer un système de cavalerie qui ne pouvait tenir que durant les trente glorieuses, lorsque l'augmentation de la richesse était de loin supérieure à ce qu'elle est actuellement.

Mêmes les États-Unis d'Amérique qui sont encore la première puissance économique mondiale sont touchés puisque depuis une dizaine de jours, toute l'administration fédérale est fermée pour cause de différend budgétaire. Loin de moi l'idée de donner un avis sur ce shutdown, contrairement à la situation française, je n'en connais ni les tenants ni les aboutissants, mais lorsqu'un pays commence à avoir 17 000 milliards de dollards de dette publique, on ne doit pas s'étonner de devoir faire des coupes budgétaires ici ou là.

Fig. 1 : sites internet des administrations américaines en drapeau

Ne nous trompons pas, nous sommes très proche de la situation des USA puisque notre dette publique tourne joyeusement autour de 2 000 milliards d'euros et ne cesse de croître. La question est maintenant de savoir si nous pouvons encore continuer à vivre continuellement au-dessus de nos moyens. Plusieurs écoles s'affrontent.

L'école que j'appellerais mélenchoniste à courte vue et au couteau entre les dents prétend qu'il suffit d'annuler cette dette en signalant aimablement mais fermement aux créanciers de l'état français que ce même état ne remboursera jamais. Très bien. C'est révolutionnaire et totalement idiot comme toute révolution. D'un autre côté, pour avoir tenté de discuter avec un membre haut placé du Front de Gauche pas plus loin que dans ces pages, souvenez-vous, comment en attendre autre chose ? En effet, si sur le papier il est très intéressant d'annuler purement et simplement notre dette, qu'en sera-t-il lorsque nous aurons à nouveau besoin d'emprunter ? Le leit motiv du Front de Gauche est que sans les charges de la dette, notre budget serait à l'équilibre. Foutaises ! Ces trois dernières années, les différents gouvernements ont créé pour 70 milliards d'euros de nouveaux impôts en augmentant les dépenses de 75 milliards. Le raisonnement ne résiste donc pas à l'analyse. Par ailleurs, une partie de cette dette est détenue par des petits épargnants. Qu'adviendra-t-il lorsque l'état leur dira que leurs économies placées à la banque et durement acquises seront perdues ? Restons donc sérieux et oublions les théories économiques du Front de Gauche.

Une autre école consiste à payer cette dette en faisant fonctionner la planche à billets, donc par l'inflation ou la dévaluation. Là encore, ce ne serait une solution viable que si le budget de l'état était à l'équilibre en absence de charge de la dette. Dans tous les autres cas, ce ne serait qu'une cavalerie de plus. Les plus vieux se souviendront avec une larme des trois dévaluations successives du franc français de la première moitié des années 1980.

La dernière solution est un remboursement de cette dette et une orthodoxie budgétaire. Mais il y a deux freins et non des moindres : d'une part une nouvelle augmentation des impôts et d'autre part une cure d'austérité drastique.

Je gage que la solution sera un mélange d'augmentation des impôts, d'austérité et d'inflation puisque la banque centrale européenne n'annoncera jamais une dévaluation de l'euro. Néanmoins, aucun gouvernement ne prendra le risque politique de le faire. En effet, tous les gouvernements récents, sans exception, ne cherchent qu'à faire perdurer un système à bout de souffle, sans doute parce qu'ils savent que les électeurs finiraient par voter pour leur intérêt particulier plutôt que pour l'intérêt général.

Or l'intérêt général n'est pas quelque chose qui va faire rêver les foules. L'intérêt général à long terme passe par une réduction drastique des dépenses, donc par une diminution du mille-feuille administratif, par la suppression de tout un tas de prestations sociales à l'efficacité douteuse et par une orthodoxie budgétaire, la première chose étant de revenir au bon vieux système soit disant archaïque de l'ancien régime qui faisait correspondre à chaque classe de dépenses une caisse différente. L'électeur ne choisira pas tout seul cette voie. La preuve est qu'il préfère actuellement voter Front National (un parti qui n'a toujours rien compris des mécanismes de base de l'économie) ou Front de Gauche (il est amusant de voir comment les deux fronts se rejoignent sur leur compréhension de l'économie) alors qu'il faudrait voter pour des gens qui ont une certaine maîtrise des mécanisme économiques. De la même manière, comment demander à un homme politique, dont la politique est un métier plus qu'une vocation, de supprimer son poste ?

Bizarrement, des pays comme l'Allemagne, la Belgique ou la Suisse s'en tirent bien mieux que nous. Souvent, avec des budgets publics inférieurs en proportion du PIB. Chose remarquable, tous ces pays ont des structures fédérales, c'est-à-dire que les décisions concernant les citoyens sont prises localement. Les dépenses y sont aussi gérées localement pour éviter au maximum les dérives.

Mais sans doute un pays comme la Suisse est-il sous-développé puisqu'un suisse gagnant annuellement 200000 CHF ne donne à l'état que 25% de ses revenus, tous impôts, taxes et assurances maladie confondus. À titre de comparaison, nous ne sommes pas loin de 60% en France pour les mêmes revenus bruts.

Il existe donc des pays en voie de développement et d'autres en voie de sous-développement. Prenons garde !

 

Anatomie d'un langage de programmation

08.10.13 | par Le Grincheux | Catégories: Je hais l'informatique, Matheux pervers

Comme demandé récemment, je vais tenter d'expliquer ici ce qu'est pour moi un bon langage de programmation. Je suis souvent sidéré du panurgisme patent du microcosme du développement informatique prétextant que si tout le monde utilise tel ou tel langage, on ne risquera rien à développer dans ce langage précis. Accessoirement, cela permet de se garantir des échecs dus au choix du langage en rappelant à qui veut bien l'entendre que tout le monde aurait fait de même.

Le système de défense me paraît un peu court.

En effet, il existe au moins trois types de langages :

  • les langages écrits par des informaticiens pour des informaticiens (exemples : C, C++, Forth, liste non exhaustive) ;
  • les langages écrits par les informaticiens pour des scientifiques (exemples : Fortran, Ada, Lisp, liste non exhaustive elle aussi) ;
  • les langages de prototypage (souvent mauvais comme Matlab, Python, liste encore moins exhaustive).

Les deux premières catégories doivent pouvoir être compilées ou semi-compilées. Quant à la troisième, rien ne s'oppose à ce qu'elle soit interprétée. Et chacun des langages peut être impératif, procédural, fonctionnel, objet voire ne ressembler à rien de connu. Il existe dans le bizarre, l'ésotérique ou le carrément mal foutu mais utilisé un nombre de langages assez impressionnant dont php et Perl.

Commençons par regarder de près les différents paradigmes de programmation et éludons immédiatement celui de la programmation impérative (typiquement celle des Basic historiques ou du Cobol à l'ancienne) qui n'a aucun intérêt sur les calculateurs modernes. La programmation impérative se justifiait à une époque où les piles des processeurs étaient limitées et où l'on n'avait pas encore inventé autre chose. Aujourd'hui, c'est une hérésie.

Un peu plus complexes, les langages procéduraux ou fonctionnels sont intéressants. Ils permettent une bonne isolation des données et sont structurés. Les données procèdent des programmes, ce qui est assez logique. En d'autres termes, le développeur écrit un programme qu'il va appliquer sur des données. En revanche, à l'autre bout du tableau figurent les langages orientés objets. Le concept de langage objet poussé à l'extrême revient à affirmer que les programmes procèdent des données. Il s'agit donc dans un premier temps de décrire les structures des données utilisées avant d'écrire les méthodes permettant de les manipuler. C'est, d'un point de vue logique assez intéressant, mais d'un point de vue de la consommation des ressources totalement contre-productif. En effet, manipuler des objets sous la forme de classes qui héritent d'un ou de plusieurs parents et qui contiennent des fonctions virtuelles résolues ou non lors de la compilation ne se fait qu'avec une débauche de mémoire et de temps processeur.

Pour fixer les idées, je vais évoquer une petite expérience. J'ai dû utiliser un algorithme de recherche du meilleur chemin dans un graphe orienté, le graphe en question contenant 15 millions d'arcs orientés. J'avais estimé que sur une machine de calcul munie de 8 Go de mémoire, cela devait passer sans aucun problème. Étant d'une fainéantise crasse, j'ai tenté de réutiliser la fonction A* de la bibliothèque Boost, programmée en C++. J'ai rapidement abandonné l'idée, les 8 Go de mémoire suffisant à peine à faire tourner un calcul. En implantant le même algorithme A* en RPL/C (un langage inspiré du C, procédural, permettant de s'interfacer avec le RPL/2), j'ai divisé l'empreinte mémoire du graphe par 20 et le temps d'exécution par 25. En effet, avec un langage procédural ou fonctionnel, lorsqu'on demande une banane, on la prend dans le panier. On n'est pas contraint à appeler un singe qui vient avec tous ses copains de la jungle pour apporter la banane.

Ainsi, un langage efficace du point de vue des ressources de la machine est un langage procédural ou fonctionnel. Le langage impératif est efficace, mais n'offre pas d'isolation entre les données des différents sous-programmes.

Parlons de la syntaxe et des fonctionnalités d'un langage. Il n'est pas tout de déclarer qu'un langage efficace du point de vue de la machine et non des neurones du développeur doit être procédural ou fonctionnel (risquons même le fonctionnel impur), faut-il encore que sa syntaxe évite les erreurs grossières, voulues ou non. En effet, il y a plusieurs écoles de pensée radicalement différentes. D'un côté se trouvent les langages où tout est permis, langages bizarrement écrits dans la période suivant 1968. Sans doute un relicat du slogan il est interdit d'interdire… Figurent dans cette classe les langages comme le C. Le compilateur ne fait aucune vérification sur l'air du « vous l'avez voulu ? Eh bien tant pis pour vous ! ». Les résultats peuvent être assez dramatiques, allant de la simple violation d'accès à l'explosion d'ariane V.

Là, il me faut tout de même parler de l'opérateur d'affectation. En C comme dans l'immense majorité des langages, il s'agit du signe « = ». Logique me direz-vous. Mais comme en C, contrairement au Basic, il est possible d'écrire plusieurs expressions encapsulées les unes dans les autres et qu'il est aussi possible d'omettre implicitement les comparaisons à 0 et que, selon l'implantation, l'évaluation d'une expression contenant des et logiques peut se faire de gauche à droite et s'arrêter à la première sous-expressions fausse, on peut trouver des choses amusantes qui ressemblent à :

if ((options == (__WCLONE|__WALL)) && (current->uid = 0))
retval = -EINVAL;

Vous ne revez pas. Cette ligne était une backdoor introduite dans le noyau Linux quelque part entre les noyaux 2.4 et les 2.6. Comment est évaluée l'expression du test ? Si la variable options vaut exactement __WCLONE|__WALL, le résultat de la première sous-expression est vrai et l'exécution se poursuit par l'évaluation de current->uid = 0 qui n'est pas un test mais une affectation. Comme la valeur affectée est nulle, la clause de test est toujours fausse et le programme ne positionne jamais retval. Au passage, l'uid courant passe à 0, ce qui donne les droit root au programme utilisant cet appel système avec les paramètres __WCLONE|__WALL. Propre, efficace et parfaitement licite du point de vue du C.

Je passe sous silence le bloc de commandes

retval = -EINVAL;

qui n'est pas délimité car réduit à une seule expression. Que se serait-il passé si par pure étourderie un point-virgule avait malencontreusement terminé la ligne précédente ? Un bloc de programme ne doit jamais être défini implicitement. Comme il ne doit pas être défini non plus en fonction de la forme comme en Python.

Dans un langage à la syntaxe bien conçue, cela ne devrait jamais arriver. Un test doit toujours être explicite en notation algébrique et les blocs doivent être clairement indiqués. Par ailleurs, utiliser une répétition de symbole « == » comme opérateur de test alors que le symbole « = » correspond à une affectation est une aberration. À minima, il faudrait écrire :

if ((options.eq.(__WCLONE+__WALL)).and.(current%uid.eq.0)) then
retval = -EINVAL
end if

Si par malheur l'opérateur de comparaison « .eq. » avait été remplacé par une affectation, le compilateur aurait refusé de faire son œuvre. Le compilateur C aurait tout aussi bien pu râler parce qu'il effectue une opération booléenne entre un booléen et un entier. Mais comme cela n'est pas interdit en C, il ne trouve rien à y redire. Des choses plus amusantes peuvent être écrites en C comme :

unsigned char *ptr;
...
if ((!ptr) && (ptr->n == 0)) retval = -EINVAL;

Je vous laisse deviner le résultat si le compilateur ne s'arrête pas à la première sous-expression fausse ou s'il décide de ne pas évaluer l'expression de gauche à droite. Sans compter le fait que le pointeur NULL n'est pas forcément défini comme étant 0x0. J'ai un souvenir d'un système sur lequel NULL valait 0x1. De deux choses l'une, soit le compilateur considère alors qu'un test !ptr était implicitement fait par rapport à NULL et non à 0 parce que l'opérande est un pointeur, soit il s'en tient à un comportement qui n'est pas plus bête qui consiste à comparer l'adresse par rapport à 0. Passons. Dans 99,9% des cas, le compilateur est gentil et fait ce que le développeur lui demande implicitement. Restent les 0,1% des cas.

Un autre problème et une source d'ennuis incommensurable. Dans la plupart des langages, les données sont typées parce que les variables doivent être déclarées et qu'une donnée ne peut exister en dehors d'une variable. Hormis quelques langages à inférence de types, l'immense majorité des langages considère que les données doivent avoir un type et un seul, que ce type soit affecté explicitement lors de la déclaration de la variable, cas du C, d'Ada, du Cobol, de Java ou du Fortran, ou qu'il le soit implicitement en fonction du nom de cette variable comme en Basic. Le problème sous-jacent est alors le choix de la structure algébrique dans laquelle les calculs vont se faire.

Si lors de calculs en flottants, la majorité des langages est tombée d'accord pour travailler sur la droite achevée réelle, le cas est un peu différent lors des calculs en entiers. Certains langages utilisent une arithmétique brutale en complément à deux sans aucune vérification d'intégrité. Ainsi, si une variable est déclarée sur un octet, 127+1 donne… -128 ! Sans aucune erreur récupérable par le programme. D'autres langages considèrent que 127+1 vaut toujours 127. D'autres encore génèreront une erreur de dépassement. Aucun des résultats n'est mathématiquement acceptable. De la même façon, l'extraction de la racine de -1 provoquera une erreur même si -1 est déclaré comme un flottant.

Un langage — je parle ici d'un langage destiné à des calculs, pas à un langage comme le C destiné surtout à l'écriture de systèmes d'exploitation et de programmes de bas niveau — doit donc pouvoir changer le type de la donnée au vol en fonction du résultat d'une commande. Si un calcul ne peut se faire jusqu'au bout en entier, il doit passer automatiquement en flottant voire en complexe. Mais cela ne peut se faire de façon efficace que si les données existent indépendamment des variables, ce qui implique un langage à pile comme le Forth.

Mais le Forth n'est pas satisfaisant car il n'utilise ni pile banalisée ni typage fort. C'est au développeur de savoir ce qu'il a empilé, combien d'emplacements sur la pile cela prend et comment il doit les relire. Ainsi, si le Forth permet de coder très rapidement des petits programmes, son utilisation devient assez rapidement très complexe et fastidieuse.

Un dernier problème et non des moindres. La gestion de la mémoire, de la pile système et, insidieusement, celle des goto's considérés comme nuisibles par certains. La mémoire peut être gérée de façon explicite par allocation dynamique, donc par augmentation de la taille du tas, ce qui est le cas avec les fonctions allocate() du Fortran, malloc() du C et new du C++. En C++, new crée un nouvel objet en appelant son constructeur. Sauf erreur manifeste du programme, le delete correspondant va se charger de libérer toute la mémoire occupée par cet objet (pas forcément dans le sens contraire aux appels effectués par new, ce qui peut poser des problèmes complexes dans le cas de fonctions virtuelles). Mieux, si l'objet est alloué comme une variable automatique, l'appel au destructeur sera implicite lors du retour de la fonction. L'utilisateur n'a donc pas à se soucier des problèmes de gestion de la mémoire. En C et en Fortran, il faut explicitement appeler deallocate() ou free(). Le compilateur ne le fera pas de son propre chef. Il faut donc savoir très exactement ce que l'on fait et quand on doit le faire. En cas de retour anticipé d'une fonction, par exemple en cas d'erreur, ce qui est fait automatiquement en C++ la plupart du temps doit se faire à la main dans d'autres langages. Et c'est généralement là qu'on rigole ! Ou qu'on pleure, c'est selon. J'ai eu l'occasion de fréquenter des doctorants, pourtant spécialistes des mathématiques qui s'évertuaient à coder des bouts de programmes en C en effectuant des malloc() à chaque besoin de mémoire sans jamais ne penser à appeler free(). Pourquoi en C ? Parce qu'un marteau, c'est tellement pratique pour enfoncer un clou lorsqu'on n'a jamais vu de tournevis ! Ce qui aurait été trivial en Fortran ne l'était réellement pas pour eux en C parce qu'ils ne maîtrisaient pas du tout le langage ni ses implications.

Et le rapport avec les goto's, me direz-vous ? Il est pourtant assez simple. La plupart des langages autorise ces branchements à l'intérieur d'une procédure. C'est pratique, cela économise souvent l'écriture de boucles longues et fastidieuses sous l'air de un goto et ça repart ! Mais cela impose aussi au compilateur de réserver sur la pile toutes les variables automatiques en début de procédure même si celles-ci ne sont utilisables que dans un bloc de programme. La conséquence de ce choix est que seule l'analyse syntaxique effectuée durant la compilation permet de masquer ces variables. Sans cela, l'utilisation des goto's aboutirait à une corruption de la pile système ou à une complexité démentielle. Le corollaire de la disponibilité du goto dans un langage est un côté implicitement statique des variables déclarées dans des blocs de programme à moins que le compilateur ne fasse un travail d'allocation spécifique et coûteux.

Une réflexion de quelques années sur tous ces problèmes et la rencontre avec des doctorants n'ayant aucune compétence en développement informatique mais étant contraints de programmer des algorithmes m'a décidé de me pencher sur ces différents problèmes. Un langage utilisable par un non spécialiste de l'architecture des systèmes, typiquement un mathématicien ou quelqu'un qui n'a pas à connaître les entrailles des calculateurs pour écrire un programme, doit répondre aux caractéristiques suivantes :

  • langage procédural ou fonctionnel impur ;
  • langage à inférence de type ;
  • séparation stricte de la notion de donnée de celle de variable, la variable n'étant qu'une donnée de type nom référençant une autre donnée ;
  • aucune allocation ou libération de la mémoire explicite, aucun accès à des pointeurs ;
  • aucune instruction de type GOTO, mais possibilité de sortir d'une boucle par anticipation ou de boucler par anticipation ;
  • évaluation de tous les éléments d'une expression même si le résultat est connu d'avance ;
  • extension des domaines de définition des fonctions mathématiques pour garder autant que possible un résultat exact à la précision près du processeur ;
  • aucun mécanisme d'affectation en notation algébrique ;
  • des garde-fous pour éviter les erreurs manifestes (éléments en dehors d'un tableau…) ;
  • séparation du fond et de la forme.

La somme de tous ces critères aboutit à un langage utilisant la notation polonaise inversée sans laquelle le troisième critère n'est pas atteignable, semi-compilé et à préprocesseur. Ce langage, quoique très structuré, ne connaît pas la notion de ligne. Il permet de se concentrer sur l'écriture d'un algorithme au sens mathématique du terme tout en évitant de se poser les questions inhérentes à l'architecture cible.

Ceux qui sont intéressés par mes travaux trouveront plus d'informations ici.

 

Pages: 1 ... 86 87 88 ...89 ... 91 ...93 ...94 95 96 ... 184