SELF PRINTERS IN C The definition of self printers is straightforward --- they are simply programs that print themselves or print their source codes, that is. You may have seen these programs before. Self-printers sparked my interest when I was in high- school. My friend asked me if could make a PASCAL program that could print itself. I stood up to his challenge and four hours later, I came up with something like: begin write('begin write(''begin write(''begin write(''... ...and a conclusion: it's a waste of time. Days later I tried to do the same trick in C and viola! I came up with the program below after a few minutes. listing 1. self01.c char*s="char*s=%s;main(){printf(s,s);}{";main(){printf(s,s);} What a program like this really needs is something that does double work, a literal that can be made to print itself twice. In this case, the variable s which is a character string. Using printf(), it is possible to do this because of the unique way that this function formats its output. For example, given the following code fragment: char *d = "x%s"; printf(d, d); you should be able to produce the output: xx%s clearly demonstrating that d does the double work of specifying the print format and printing itself. So given that, the program in listing 1 should be able to print itself. Or so I thought. So what's wrong with it? As can be seen in a sample run of the program: output of self01.c char*s=char*s=%s;main(){printf(s,s);}{;main(){printf(s,s);} it is clear that it's missing the double qoutes that delimit the literal value of char*s. In the next program, I fixed the bug and came up with a correct output. It should work on systems that maps the numeric value 34 to the character \" (ASCII). listing 2. self02.c char*s="char*s=%c%s%c;int q=34;main(){printf(s,q,s,q);}"; int q=34;main(){printf(s,q,s,q);} I won't bother to show the output of this and the other programs below, they're self- printers all. listing 3. self03.c char*s="char*s=%c%s%c;%cint q=34,n=10;main(){printf(s,q,s,q,n);}"; int q=34,n=10;main(){printf(s,q,s,q,n);} listing 4. self04.c char *s1="char *s1=%c%s%c;%cchar *s2=%c%s%c;%cchar *s3=%c%s%c;%c"; char *s2="int q=34,n=10;%cmain()%c{%c printf(s1,q,s1,q,n,q,s2,q,n,q,s3,q,n);"; char *s3="%c printf(s2,n,n,n);%c printf(s3,n,n,n);%c}"; int q=34,n=10; main() { printf(s1,q,s1,q,n,q,s2,q,n,q,s3,q,n); printf(s2,n,n,n); printf(s3,n,n,n); } The program in listing 2 is the shortest I could ever code. If you have something shorter, please tell me about it.
- Mark J. P. Documento
javelinexxx@yahoo.com
Any loss of sanity effected by the perusal of the above article will not be a responsibility of the author.
God knows he has enough of this problem himself.
The following response came from mail to the article above which I published at the
Planet Source Code.
Mark, Since you have an interest in self-producing 'C' code, you might be interested in http://www.ioccc.org/. It's the home page for the International Obfuscated C Code Contest. It's a contest to see who can produce the ugliest, most confusing piece of functional c code. They used to run a shortest self-producing C code contest until someone won by submitting a blank cpp file. Because of an old Unix compiler glitch you could compile a blank file, and it would produce an executable that ran and did nothing. And since you can direct input from a program to a file in the Unix world. You could direct the results of this program to a file, and the result would be an empty file. So this kind of end that contest. And the point of this long e-mail is...... They have an archive of all the code from past winners, and you will find some nice examples of self-replicating code. Along with a bunch of interesting/ugly c and cpp code. Sorry, I didn't intend this e-mail to be this long. Ryan Ryan Smulan <smulanry@uregina.ca>
Back to Tutorials and Articles