Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Program which source code is exactly the same as its output [duplicate]

The more I try to understand this perplexed enigma the more I want to give up.

char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}

How is happening for this one-line source code to generate exactly the same output when the program executes and is there any common notion for this kind of programs?

like image 707
Imobilis Avatar asked Aug 28 '15 09:08

Imobilis


3 Answers

This is called a Quine.

So let's see what main() does:

printf(s,34,s,34);

34 is the ASCII code for the character " (double quote), so this is the same as:

printf(s, '"', s, '"');

The first argument to printf(3) is the format string. The string passed is:

"char *s = %c%s%c; main(){printf(s,34,s,34);}"

So, printf(3) will output exactly that, but note the %c, %s and %c format specifiers, which instruct printf(3) to print a character, followed by a string, followed by another character in that place, which are respectively the 2nd, 3rd and 4th arguments.

The characters, as we saw, are both ", and the string is s again (the same string). So the program output is:

char *s = "X"; main(){printf(s,34,s,34);}

Where X is the string s in the program. So we get this as output:

char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}

Which, interestingly, is the program source itself.

like image 128
Filipe Gonçalves Avatar answered Oct 12 '22 10:10

Filipe Gonçalves


take that string from first parameter of printf:

'char *s = %c%s%c; main(){printf(s,34,s,34);}'

and do substitution where

%c = 34 = '"' //(same for both %c)
%s = 'char *s = %c%s%c; main(){printf(s,34,s,34);}'

printf will do substitution only once (not recursive), so result is:

'char *s = "char *s = %c%s%c; main(){printf(s,34,s,34);}"; main(){printf(s,34,s,34);}'
like image 33
Ormei Avatar answered Oct 12 '22 10:10

Ormei


To understand the code, first simplify and reformat:

char *s = "some format string";
main() {
    printf(s,34,s,34);
}

so it uses s as a formatting string to print three entities: 34, the string s itself and 34. In this case, the important part of the formatting string s is:

char *s = "... %c%s%c ..."

which means the two 34s become double-quotes (") and the formatting-string s is just printed as a normal string. Now you should see the the rest of the formatting-string s is just a copy of the whole program.

like image 41
TripeHound Avatar answered Oct 12 '22 10:10

TripeHound