![]()
Récréation ![]()
![]()
![]()
![]()
![]()
Suivant: Le préprocesseur Début: Les expressions Précédent: Sémantique des expressions
Paragraphes
Récréation
Voici en illustration de l'opérateur~
, la contribution de Jack Applin a la compétition du code C le plus obscur (IOCCC) de 1986. Ce programme a la propriété extraordinaire d'être un source valide à la fois pour le shell/bin/sh
, le langage C et FORTRAN ! Voici le source :cat =13 /*/ >/dev/null 2>&1; echo "Hello, world!"; exit * * This program works under cc, f77, and /bin/sh. * */; main() { write( cat-~-cat /*,'( */ ,"Hello, world!" , cat); putchar(~-~-~-cat); } /* ,)') end */La version shell
La commandecat =13
est une commande incorrecte (à cause du blanc entrecat
et le signe =), mais comme l'erreur standard est redirigée sur/dev/null
, le message d'erreur n'apparaît pas. Ensuite, l'echo imprime << Hello world >>, puis le shell fait exit. Le reste du source lui est donc indifférent. Ensuite, les deux versions C et fortran sont mélangées grâce à un emploi judicieux des commentaires (en fortran, toute ligne commençant par*
ouc
est un commentaire).La version fortran
Une fois débarrassé des commentaires fortran, le source devient :write( *,'("Hello, world!")') endce qui imprime << Hello world >>.La version C
Après nettoyage des commentaires C, le source original devient :cat =13 ; main() { write( cat-~-cat ,"Hello, world!" , cat); putchar(~-~-~-cat); }La déclaration cat =13 ; est valide en C K&R mais obsolète en ANSI C : elle est équivalente à int cat =13 ; Cette forme est cependant encore généralement acceptée (avec un warning) par les compilateurs. La suite ne fonctionne correctement que sur une machine satisfaisant aux deux contraintes suivantes :
Donc
- 1.
- être une machine UNIX pour disposer de l'appel noyau write ;
- 2.
- avoir les entiers négatifs représentés en complément à 2. Dans ce cas en effet,
~-x
vautx - 1
.cat-~-cat
vaut 1 qui, en premier paramètre de write désigne la sortie standard, et~-~-~-13
vaut 10 (le code de newline). Le troisième paramètre passé à write doit être la longueur de la chaîne à imprimer, ici 13 qui est bien la longueur deHello, world!
. Au final, ce programme imprime << Hello world >>.
30/9/1997