The Art of Writing Your Self-Replicating Quine

July 16, 2023 at 11:43:00, written by @vmmon.th0


A quine is a computer program which takes no input and produces a copy of its own source code as its only output. This intriguing property highlights the program's ability to self-replicate.

The purpose of this Archive is to show you an interesting example of a quine in C-LANG with these constraints, which i discovered during my studies :

First of all, if these constraints don't make sense at the moment, just tell yourself that it's part of a self-replication process and that it's a way of building a quine. We will demonstrate the abstraction between the Quine and the Self replication part with the above constraints. Let’s start with the fundamental concept.

The Quine

In order to produce a quine we can imagine writing something like this: A program that prints its own source code stores in a macro for example, it respects its properties.

#define QUINE "#define QUINE..."

Do you see the first complication ? We are perpetually redefining ourselves through hard-coding. Below, I provided you a trivial and complete quine.

#include <stdio.h>
#define QUINE "#include <stdio.h>%3$c#define QUINE %2$c%1$s%2$c%3$cint%3$cmain(void)%3$c{%3$cprintf(QUINE, QUINE, 34, 10);%3$c}"
printf(QUINE, QUINE, 34, 10);

Notice that we solved the problem by using a argument specifier and a type specifier. In other words, instead of perpetually redefining ourselves, we pass the definition of the quine as an argument.

Here is an example to understand how the argument and type specifier operates :

printf("Characters: %3$c %1$c %2$c\n", 'A', 'B', 'C');

It would print: Characters: C A B. Here, %3$c prints C, %1$c prints A, and %2$c prints B, in that order.

In order to test our quine, simply compile the program and compare the output with the source code since it is supposed to be an identical replication.

clang main.c -o quine
diff <(./quine) main.c

The Self-replicating Quine

Here is a self-replicating quine with the constraints mentioned at the beginning. This program is a variation of a classic quine, it works very simply :

  1. Definition and Initialization: The program defines a macro representing its own source code and initializes a variable X to 5.
  2. Check and Decrement: It checks if the source file name contains a _ and decrements X if it does.
  3. Writing New Source File: Creates a new source file (Sully_X.c) with the current code, where X is its current value.
  4. Compilation and Execution: Compiles the new source file into an executable and executes it if X is greater than 0.
  5. Replication: Each run produces a similar file and executable with X decreased by 1, until X reaches 0.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define QUINE "#include <stdio.h>%1$c#include <stdlib.h>%1$c#include <string.h>%1$c#define QUINE %2$c%3$s%2$c%1$c%1$cint X = %4$d;%1$c%1$cint%1$cmain(void)%1$c{%1$cchar next_file[11];%1$cchar next_exec[11];%1$cif ((strchr(__FILE__, '_')) != NULL)%1$c{%1$c--X;%1$c}%1$csprintf(next_file, %2$cSully_%%d.c%2$c, X);%1$csprintf(next_exec, %2$cSully_%%d%2$c, X);%1$cFILE* fffffff;%1$cfffffff = fopen(next_file, %2$cw%2$c);%1$cif (fffffff == NULL)%1$c{%1$creturn -1;%1$c}%1$cfprintf(fffffff, QUINE, 10, 34, QUINE, X);%1$cfclose(fffffff);%1$cchar cmdline[100];%1$csprintf(cmdline, %2$cclang -Wall -Wextra -Werror %%s -o %%s%2$c, next_file, next_exec);%1$csystem(cmdline);%1$cif (X > 0)%1$c{%1$csprintf(cmdline, %2$c./%%s%2$c, next_exec);%1$csystem(cmdline);%1$c}%1$creturn 0;%1$c}"

int X = 5;

char next_file[11];
char next_exec[11];
if ((strchr(__FILE__, '_')) != NULL)
sprintf(next_file, "Sully_%d.c", X);
sprintf(next_exec, "Sully_%d", X);
FILE* fffffff;
fffffff = fopen(next_file, "w");
if (fffffff == NULL)
return -1;
fprintf(fffffff, QUINE, 10, 34, QUINE, X);
char cmdline[100];
sprintf(cmdline, "clang -Wall -Wextra -Werror %s -o %s", next_file, next_exec);
if (X > 0)
sprintf(cmdline, "./%s", next_exec);
return 0;

Finally, if you have been careful, this one does not respect an identical replication being that the integer X will be modified, and that is why it remains a variation that keeps the same behavior except this detail.

For comments, please send me an dm through contact section.