International Obfuscated C Code Contest
Le International Obfuscated C Code Contest en français : « Concours international de code C obscur » est un concours de programmation organisé chaque année depuis 1984 (à l'exception de 1997, 1999, 2002 et 2003). Il y a plusieurs entrées gagnantes chaque année, et chaque année rentre dans une catégorie du genre : « Plus grand abus du préprocesseur C » ou « Comportement le plus incohérent ».
Origine
Les IOCCC ont été lancés par Landon Curt Noll (en) et Larry Bassel. Ils étaient en train de parler du code abominable dont ils devaient faire la maintenance dans leur travail quotidien. Ils décidèrent alors d'organiser un concours du pire code C possible. Dans l'espace autorisé de seulement quelques kilooctets, les participants réussissent à faire des choses compliquées : le vainqueur de 2004 s'est révélé être un système d'exploitation.
Citations
Quelques citations des vainqueurs et du jury de 2004 incluent :
- « Pour simplifier les choses, j'ai évité le préprocesseur C et les instructions compliquées comme « if », « for », « do », « while », « switch », et « goto »[1],[2]. »
- « Nous ne sommes toujours pas sûrs d'avoir un programme utile, mais c'est la première fission atomique vue sur les IOCCC.[3],[4] »
- « Le programme implémente une ALU de 11 bits dans le préprocesseur. »
- « Je me suis aperçu que calculer les nombres premiers jusqu'à 1 024 fait s'inclure le programme lui-même plus de 6,8 millions de fois[5],[6]. »
Exemples
Un exemple d'entrée est[7],[8] :
#define _ -F<00||--F-OO--;
int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
{
_-_-_-_
_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_
_-_-_-_
}
Ce programme calcule pi en regardant sa propre surface ; une valeur plus précise peut être obtenue en utilisant un programme plus grand (cette entrée a été écrite en C K&R ; telle quelle, elle ne compile pas en C ANSI[note 1].)
Un autre exemple est un simulateur de vol qui a gagné l'IOCCC en 1998[9] :
#include <math.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
double L ,o ,P
,_=dt,T,Z,D=1,d,
s[999],E,h= 8,I,
J,K,w[999],M,m,O
,n[999],j=33e-3,i=
1E3,r,t, u,v ,W,S=
74.5,l=221,X=7.26,
a,B,A=32.2,c, F,H;
int N,q, C, y,p,U;
Window z; char f[52]
; GC k; main(){ Display*e=
XOpenDisplay( 0); z=RootWindow(e,0); for (XSetForeground(e,k=XCreateGC (e,z,0,0),BlackPixel(e,0))
; scanf("%lf%lf%lf",y +n,w+y, y+s)+1; y ++); XSelectInput(e,z= XCreateSimpleWindow(e,z,0,0,400,400,
0,0,WhitePixel(e,0) ),KeyPressMask); for(XMapWindow(e,z); ; T=sin(O)){ struct timeval G={ 0,dt*1e6}
; K= cos(j); N=1e4; M+= H*_; Z=D*K; F+=_*P; r=E*K; W=cos( O); m=K*W; H=K*T; O+=D*_*F/ K+d/K*E*_; B=
sin(j); a=B*T*D-E*W; XClearWindow(e,z); t=T*E+ D*B*W; j+=d*_*D-_*F*E; P=W*E*B-T*D; for (o+=(I=D*W+E
*T*B,E*d/K *B+v+B/K*F*D)*_; p<y; ){ T=p[s]+i; E=c-p[w]; D=n[p]-L; K=D*m-B*T-H*E; if(p [n]+w[ p]+p[s
]== 0|K <fabs(W=T*r-I*E +D*P) |fabs(D=t *D+Z *T-a *E)> K)N=1e4; else{ q=W/K *4E2+2e2; C= 2E2+4e2/ K
*D; N-1E4&& XDrawLine(e ,z,k,N ,U,q,C); N=q; U=C; } ++p; } L+=_* (X*t +P*M+m*l); T=X*X+ l*l+M *M;
XDrawString(e,z,k ,20,380,f,17); D=v/l*15; i+=(B *l-M*r -X*Z)*_; for(; XPending(e); u *=CS!=N){
XEvent z; XNextEvent(e ,&z);
++*((N=XLookupKeysym
(&z.xkey,0))-IT?
N-LT? UP-N?& E:&
J:& u: &h); --*(
DN -N? N-DT ?N==
RT?&u: & W:&h:&J
); } m=15*F/l;
c+=(I=M/ l,l*H
+I*M+a*X)*_; H
=A*r+v*X-F*l+(
E=.1+X*4.9/l,t
=T*m/32-I*T/24
)/S; K=F*M+(
h* 1e4/l-(T+
E*5*T*E)/3e2
)/S-X*d-B*A;
a=2.63 /l*d;
X+=( d*l-T/S
*(.19*E +a
*.64+J/1e3
)-M* v +A*
Z)*_; l +=
K *_; W=d;
sprintf(f,
"%5d %3d"
"%7d",p =l
/1.7,(C=9E3+
O*57.3)%0550,(int)i); d+=T*(.45-14/l*
X-a*130-J* .14)*_/125e2+F*_*v; P=(T*(47
*I-m* 52+E*94 *D-t*.38+u*.21*E) /1e2+W*
179*v)/2312; select(p=0,0,0,0,&G); v-=(
W*F-T*(.63*m-I*.086+m*E*19-D*25-.11*u
)/107e2)*_; D=cos(o); E=sin(o); } }
Aspects considérés
Quelques aspects remarquables des entrées incluent :
- La forme du listing, qui peut ressembler à des images, du texte, etc. ;
- Des redéfinitions du préprocesseur pour rendre le code plus difficile à lire ;
- Du code auto-modifiant ;
- Le pire abus des règles : à plusieurs reprises, une entrée a été soumise qui était si évidemment absurde qu'elle a entraîné une redéfinition des règles pour les années à venir. C'est un très grand honneur. Un exemple est le plus petit programme qui s'affiche lui-même. L'entrée était un programme de taille zéro, qui, quand il était lancé, affichait zéro octet à l'écran (ça demande un usage créatif du makefile pour tomber juste)[10].
Plusieurs des entrées précédentes sont notables pour avoir causé des pannes de compilateurs (plus particulièrement celui de Visual Studio).
Notes et références
Notes
- Si l'on utilise GCC, compiler avec la ligne de commande suivante :
gcc -E r.c | sed 's/- -/--/g' > r2.c ; gcc -o r2 r2.c
(si le fichier source s'appeller.c
).
Références
- http://www.ioccc.org/years.html#2004_burley
- http://www.ioccc.org/2004/burley.hint
- http://www.ioccc.org/years.html#2004_jdalbec
- http://www.ioccc.org/2004/jdalbec.hint
- http://www.ioccc.org/years.html#2004_vik2
- http://www.ioccc.org/2004/vik2.hint
- http://www.de.ioccc.org/years.html#1988_westley
- http://www.de.ioccc.org/1988/westley.c
- IOCCC Flight Simulator.
- http://www.ioccc.org/years.html#1994_smr