Why is this quine in C mentioned by Ken Thompson in "Reflections on Trusting Trust" not working?

828 Views Asked by At

This quine I saw in an article by Ken Thompson (read here) isn't reproducing the same code. I was just curious why it's not working? is the code obsolete now?.

code of quine:

char s[] = {
        '\t',
        '0',
        '\n',
        '}',
        ';',
        '\n',
        '\n',
        '/',
        '*',
        '\n'
};

/*
 *The string s is a representation of the body
 *of this program from '0'
 * to the end
 */

main(){
        int i;

        printf("char\ts[] = {\n");
        for(i = 0; s[i]; i++)
                printf("\t%d, \n", s[i]);
        printf("%s",s);
}

output:

char    s[] = {
        9,
        48,
        10,
        125,
        59,
        10,
        10,
        47,
        42,
        10,
        0
};

/*

These are the compiler warnings on compiling (self_reproducing.c is the filename):

self_reproducing.c:20:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
   20 | main(){
      | ^~~~
self_reproducing.c: In function ‘main’:
self_reproducing.c:23:2: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
   23 |  printf("char\ts[] = {\n");
      |  ^~~~~~
self_reproducing.c:23:2: warning: incompatible implicit declaration of built-in function ‘printf’
self_reproducing.c:1:1: note: include ‘<stdio.h>’ or provide a declaration of ‘printf’
  +++ |+#include <stdio.h>
    1 | char s[] = {

Oops! I ignored the 213 lines deleted line. So the question should be —what is the whole quine that is mentioned in the article?

4

There are 4 best solutions below

8
SunGrow On

You most probably did not include "<stdio.h>" library.

just add

    #include <stdio.h>

on top of your code.

The very same solution is advised in your compiler error

5
underscore_d On

I take that "not working" to mean not 'giving compiler warnings' - because the reasons for those are self-evident - but instead what else you wrote:

This quine [...] isn't reproducing the same code

The quine is self-reproducing, once we add back (213 lines deleted) that the author abridged and you deleted - which represent the rest of the code, plus the 0 NUL terminator that ends the array of chars:

/*
 * The string s is a representation of the body
 * of this program from '0'
 * to the end
 */

Your confusion seems to stem from how the program prints the integer ASCII values of the characters in said array, but it originally declared those characters like '\t', '\n', and so on. But integers with appropriate values are valid chars, so the code is self-reproducing, even if the elements are formatted as integers instead of 'c'haracters as in the original source. Either way, we end up with an array of the same chars; just that array was initialised in a different but equivalent fashion.

Why does it print them as integers? Because that is far easier/shorter than having to quote, conditionally escape, and so on for each element. It maps to the same machine code / array contents but requires a lot less faff to program the quine.

The author even wrote this!

(The purist will note that the program is not precisely a self-reproducing program, but wIll produce a self-reproducing program.)

As for the edited/added question, the whole quine would of course add the rest of the characters needed to represent the remainder of the program. The author presumably abridged the program for the purpose of being able to more easily illustrate their point, without driving it home by taking a whole page.

0
RobertS supports Monica Cellio On

"This quine I saw in an article by Ken Thompson (read here) isn't reproducing the same code. I was just curious why it's not working?"

It does not give the expected output because it isn't meant to be a reproducible example for a "quine".

To cite Ken himself about the definition of a "quine" (emphasize mine):

"More precisely stated, the problem is to write a source program that, when compiled and executed, will produce as output an exact copy of its source."

The code shown doesn't reproduce an exact copy of its whole source code as output, because it doesn't meant to.

Ken even admit that himself (emphasize mine):

"Figure 1 shows a self-reproducing program in the C programming language. (The purist will note that the program is not precisely a self-reproducing program, but will produce a self-reproducing program.) This entry is much too large to win a prize, but it demonstrates the technique and has two important properties that I need to complete my story: ..."

and which is also proven by 213 lines deleted in Ken's code.

It is just meant to demonstrate what a "quine" program suppose to be and that its purpose is to print its source code.


"Is the code obsolete now?"

Apart from that the code is missing parts, to classify it as strict "quine",

Yes, the code is obsolete now. It was made back in 1984, before C was even standardized by ANSI and for a complete different machine like the ones we now have today.

This is proven by the warnings you get.

To compile this code without warnings and including the header file stdio.h, you would need a compiler (or a appropriate compiler option, like f.e. std=c89) which supports an implicit declaration for the printf() function, which is no longer supported since C99 (current standard is C18).

Note, that the compiler/linker will probably nonetheless link to the definition of printf() correctly, but it is an obsolete feature and not compliant to a modern standard.

Also the notation main() is no longer supported. It shall be int main (void) to be strictly standard-compliant or at least int main() which use is deprecated as it provides no prototype for main() or equivalent*, if no arguments are passed to main().

*The return type can be different but has to be compatible to an int.


"What is the whole quine that is mentioned in the article?"

It is just an example for a "quine". There is no full original example public available. Perhaps the original sleeps anywhere at an archive. But you can develop it by yourself if you follow the guideline that every piece of code needs to be outputted.


Reference "Reflections on Trusting Trust", Ken Thompson, August 1984:

3
jwdonahue On

The code sequences '/', '\t', '\n', etc., are just mnemonics used to tell the compiler what character codes to use. It saves us from having to look-up the ASCII codes for them. In the case of some of the control codes, particularly carriage returns and new-lines, the actual code is architecture dependent, so these mnemonics are also there to make the code portable across operating systems. The point of the article however wasn't about writing quine's, it was about how easily systems can be hacked by the coders who operate and maintain them, without leaving any obvious foot-prints.

Context is important here. Thomson was attacking a vintage Unix system that is unlikely to be running on anything in existence today.


From the referenced article:

In college, before video games, we would amuse ourselves by posing programming exercises. One of the favorites was to write the shortest self-reproducing program.

A "self reproducing program" makes no mention of reproducing it's own source code.