C Quine
A quine is a computer program that produces an exact copy of its own source code as its output. It must not consume any input, so tricks involving reading its own source code and printing it are not permitted.
The Classic Quine
Here is a classic quine I came across a few days ago in a mailing list:
main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}
This program is written in K&R C. The current version of GCC
compiles it fine. It is a valid quine on ASCII machines because
this program uses the integer code 34
to print the
quotation mark ("
) character. This will be explained
further in the next section. On another implementation of the C
compiler which does not use ASCII code for the quotation mark
character, the program needs to be modified to the use the correct
code.
Here are some commands that demonstrate the quine:
$ printf '%s' 'main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}' > quine.c $ cc quine.c && ./a.out > out.txt && diff quine.c out.txt $ cat quine.c; echo main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);} $ ./a.out main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}
The source code of this quine does not end with a newline.
The -n
option of GNU echo ensures that the source code
file is created without a terminating newline.
Close Look at the Classic Quine
Let us take a close look at how the quine introduced in the previous section works. Let us add some newlines in the source code of this quine for the sake of clarity.
main()
{
char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";
printf(s,34,s,34);
}
This is almost the same program presented in the previous section. Only a few newlines have been added to it to make the program easier to read.
We can see that the printf
call uses the
string s
as the format string. The format string
contains three conversion
specifications: %c
, %s
,
and %c
. The arguments for these conversions
are: 34
, the string s
itself,
and 34
once again. Note that 34
is the
ASCII code for the quotation mark character ("
). With
that in mind, let us now construct the output of
the printf
call in a step-by-step manner.
The initial portion of the output consists of the format string from the beginning up to, but not including, the first conversion specification copied unchanged to the output stream. Here it is:
main(){char*s=
Then the first conversion specification %c
is
processed, the corresponnding argument 34
is taken, and
a quotation mark is printed like this:
"
Then the second conversion specification %s
is
processed. The corresponding argument is the string s
itself, so the entire string is printed like this:
main(){char*s=%c%s%c;printf(s,34,s,34);}
Then the third conversion specification %c
is
processed. The corresponding argument is 34
again, so
once again a quotation mark is printed like this:
"
Finally, the rest of the format string is copied unchanged to produce the following output:
;printf(s,34,s,34);}
Here are all the five parts of the output presented next to each other:
main(){char*s=
"
main(){char*s=%c%s%c;printf(s,34,s,34);}
"
;printf(s,34,s,34);}
Writing them all out in a single line, we get this:
main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}
This output matches the source code of the program thus confirming that our program is a quine.
Classic Quine With Terminating Newline
The source code of the classic quine presented above does not terminate with a newline. I found that a little bothersome because I am used to always terminating my source code with a single trailing newline at the end. So I decided to modify that quine a little to ensure that it always ends with a newline. This is the quine I arrived at:
main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34,10);}%c";printf(s,34,s,34,10);}
Compared to the quine in the previous sections, this one has an
additional %c
at the end of the formal string and the
integer 10
as the corresponding argument to ensure that
the output ends with a newline. Here is a demonstration of this
quine:
$ echo 'main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34,10);}%c";printf(s,34,s,34,10);}' > quine.c $ cc quine.c && ./a.out > out.txt && diff quine.c out.txt $ cat quine.c main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34,10);}%c";printf(s,34,s,34,10);} $ ./a.out main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34,10);}%c";printf(s,34,s,34,10);}
C89 Quine
The classic C quines presented above are written in K&C. They do not conform to the C standard. However, with some modifications to the quines presented above, we can get a quine that conforms to the C89 standard:
#include <stdio.h>
int main(){char*s="#include <stdio.h>%cint main(){char*s=%c%s%c;printf(s,10,34,s,34,10);return 0;}%c";printf(s,10,34,s,34,10);return 0;}
Here is a demonstration of this quine:
$ echo '#include <stdio.h> int main(){char*s="#include <stdio.h>%cint main(){char*s=%c%s%c;printf(s,10,34,s,34,10);return 0;}%c";printf(s,10,34,s,34,10);return 0;}' > quine.c $ cc -std=c89 -Wall -Wextra -pedantic quine.c && ./a.out > out.txt && diff quine.c out.txt $ cat quine.c #include <stdio.h> int main(){char*s="#include <stdio.h>%cint main(){char*s=%c%s%c;printf(s,10,34,s,34,10);return 0;}%c";printf(s,10,34,s,34,10);return 0;} $ ./a.out #include <stdio.h> int main(){char*s="#include <stdio.h>%cint main(){char*s=%c%s%c;printf(s,10,34,s,34,10);return 0;}%c";printf(s,10,34,s,34,10);return 0;}