Climat et crainte d’UB

Licorne composée de cœurs

Le language de programmation C++ est une sorte de monstre sacré en informatique, comme il permet un accès relativement bas niveau à la machine, il produit du code très rapide, aux prix de nombreux bugs. En conséquence, les programmeurs chevronnés le traitent avec un grand respect, et apprennent à craindre ses idiosyncrasies. Un concept important quand on travaille avec ce language et celui d’Undefined Behaviour, généralement abrégé UB, en français cela se traduirait par comportement non défini.

Qu’est-ce qu’UB? Voici un example:

uint16 foo(uint16 a) {
  uint16 b = a * 2;
  return return b / 2;
}

Que fait cette fonction? À priori, elle retourne simplement la valeur passée en paramètre: la valeur a est doublée et puis divisée par deux, donc on se retrouve avec la valeur de départ. Sauf que non.

Le problème c’est que les variables sont des entiers positifs sur 16 bits, et la multiplication peut dépasser la capacité de la variable (overflow), donc par exemple si le paramètre a vaut 65534 0xfffe, le double 131068 n’est pas représentable avec un entier non signé sur 16 bits, et la valeur de b est non définie, de même que le résultat de la division par deux.

Non-défini veut fondamentalement dire que le compilateur peut faire ce qu’il veut : générer un programme qui effacer toute la mémoire, venir chez vous et vider le frigo, ou simplement se planter. Dans le cas présent, il va probablement simplifier le code et décider que cette fonction ne fait rien, que la multiplication et la division s’annulent. Le truc c’est qu’il n’est pas obligé.

Dans le cas présent, il est relativement facile d’anticiper ce que fera le compilateur, mais rapidement on tombe sur des cas bizarres et imprévisibles. Dans l’exemple ci-dessus, il pourrait tout aussi bien décider que la première multiplication est équivalente à un shift à gauche suivi d’un shift à droite, et donc que la réponse est 32766 (0x7ffe) – le comportement serait correct pour tous les cas définis.

On apprend à l’université qu’un compilateur traduit les instructions dans un language de programmation en instructions pour le processeur. Un processeur moderne est très complexe et pas du tout intuitif, et donc la fonction suivante.

int foo(int num) {
    return num  / 37;
}

peut-être traduite par la séquence suivante:

push    rbp
mov     rbp, rsp
mov     DWORD PTR [rbp-4], edi
mov     eax, DWORD PTR [rbp-4]
movsx   rdx, eax
imul    rdx, rdx, -580400985
shr     rdx, 32
add     edx, eax
sar     edx, 5
sar     eax, 31
sub     edx, eax
mov     eax, edx
pop     rbp
ret

Les plus observateurs auront noté qu’il n’y a ni division, ni instances de la valeur 37 dans le code assembleur. Le compilateur a remplacé une opération couteuse (division) par une multiplication imul par une valeur mystérieuse (-580400985) et plusieurs shifts (sar, shr), et une soustraction (sub).

Bon, mais quel rapport avec le climat ? Il y a un problème relativement défini, le réchauffement global, et des tas de changements locaux très mal définis. Il est relativement facile de penser un écart d’un demi degré, ou même d’un degré, après tout ce n’est qu’un décalage de quelques semaines dans l’année. Mais le climat est comme le compilateur C++, il a ses propres règles, et juste décaler de quelques fractions de degrés la moyenne globale représente une quantité d’énergie gigantesque, qui va faire des trucs non définis.

Une ville comme Marseille peut probablement gérer une température plus élevée, après tout, elle est dans le sud, mais qu’en est-il des autres scénarios ? La ville de Kanazawa, au Japon est environ 700 km plus au sud que Marseilles, les précipitations y sont de 2400 mm par an, environ cinq fois plus que dans la cité phocéenne (515 mm par an). À Kanazawa, non seulement il pleut beaucoup, l’hiver il neige, abondamment, au point que les arbres dans les parcs doivent être renforcés, au point que ces supports sont la signature du parc Kenroku-en qui fait la fierté de la ville.

Un seul hiver de ce genre causerait d’immenses dégâts à Marseilles, les toits s’effondreraient sous le poids de la neige, et les canalisations seraient rapidement surchargées, causant des inondations, minant les fondations. Non seulement y aurait-il de la casse, mais probablement des lourdes pertes humaines.

Les villes européennes bénéficient d’un climat relativement clément étant donné leur latitude, et ce à cause du Gulf Stream qui apporte de l’air chaud. New-York se trouve approximativement à la même latitude que Rome, et la ville de Boston est plus au sud que Marseille. Les températures minimales y atteignent souvent les -10° en hiver, avec parfois -15°. Il est parfaitement possible que le Gulf Stream s’arrête.

Là encore, un hiver de ce type causerait d’immenses dégâts : à cette température, les canalisations mal isolées gèlent, et parfois éclatent, les routes se couvrent de verglas, que la voirie n’est probablement pas prête à gérer. La maigre isolation des maisons ne protège pas les habitants, qui souffrent du froid directement, ou indirectement, s’asphyxiant avec des chauffages d’appoint – c’est ce qui s’est passé au Texas lors des pannes de courant.

Au delà des villes, il y a naturellement toute la nature autours, un example simple : s’il gèle, les oliviers meurent.

Les deux scénarios ci-dessus ne sont que des examples, il y a une pléthore d’autres possibilités, et c’est bien ça qui devrait inquiéter les gens, comme tout bon programmeurs, ils devraient craindre UB…

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.