5
\$\begingroup\$

From Wikipedia:

A quine is a computer program that takes no input and produces a copy of its own source code as its only output. The standard terms for these programs in the computability theory and computer science literature are "self-replicating programs", "self-reproducing programs", and "self-copying programs".

A quine is a fixed point of an execution environment, when that environment is viewed as a function transforming programs into their outputs. Quines are possible in any Turing-complete programming language, as a direct consequence of Kleene's recursion theorem. For amusement, programmers sometimes attempt to develop the shortest possible quine in any given programming language.

Code:

The code assumes ASCII.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    static constexpr char code[] = "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\nint main(void)\n{\n    static constexpr char code[] = \"?\";\n\n    for (size_t i = 0; i < sizeof code - 1; ++i) {\n        if (code[i] == 63) {\n            for (size_t j = 0; j < sizeof code - 1; ++j) {\n                switch(code[j]) {\n                    case '\\n': printf(\"\\\\n\");  break;\n                    case '\\\\': printf(\"\\\\\\\\\"); break;\n                    case '\"' : printf(\"\\\\\\\"\"); break;\n                    default  : printf(\"%c\", code[j]);\n                }\n            }\n        } else {\n            printf(\"%c\", code[i]);\n        }\n    }\n\n    return EXIT_SUCCESS;\n}\n";

    for (size_t i = 0; i < sizeof code - 1; ++i) {
        if (code[i] == 63) {
            for (size_t j = 0; j < sizeof code - 1; ++j) {
                switch(code[j]) {
                    case '\n': printf("\\n");  break;
                    case '\\': printf("\\\\"); break;
                    case '"' : printf("\\\""); break;
                    default  : printf("%c", code[j]);
                }
            }
        } else {
            printf("%c", code[i]);
        }
    }

    return EXIT_SUCCESS;
}

Test:

~/quine >> ./quine | diff quine.c -
------------------------------------------------------------------------------
~/quine >> 

no output, meaning success.

Review Request:

Anything. Everything.

Is there an easier way to do this with #embed? I heard LLVM Clang 19 has implemented it.


Edit: A quine that clones itself and runs some more quines is a follow-up to this question.

\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

A few comments, mostly to shrink the source text size.

  • Recommend hex instead of decimal 63 (with a comment).
  • use minimal braces
  • no return
  • static constexpr may be "unnecessary verbiage" in this instance
  • don't repeat sizeof code - 1
  • putc() where possible
  • without return EXIT_SUCCESS;, which #include could vanish?
  • is <string.h> required???
  • pointers walking the string might be easier/briefer than array notation.

Choice of ? as pivotal character prevents use of C's ternary operator (that might stand in for switch() and a lot of case text...)


Suggest breaking long line/string into fragments (compiler will concatenate), then representing each fragment within itself... Another hill to climb...

\$\endgroup\$
13
  • 1
    \$\begingroup\$ "is <string.h> required???" ==> Not anymore, I was using strlen() on data previously, but forgot to remove it. I configured my editor to automatically include <stdlib.h>, and was too lazy to remove it too. :) \$\endgroup\$
    – Harith
    Commented Jun 15 at 7:16
  • 1
    \$\begingroup\$ Why, we can even omit <stdio.h> and use the compiler's -include flag. \$\endgroup\$
    – Harith
    Commented Jun 15 at 7:25
  • 1
    \$\begingroup\$ @Harith "New fangled!!" In my day, -I dirname was all that was available... \$\endgroup\$
    – Fe2O3
    Commented Jun 15 at 7:32
  • 1
    \$\begingroup\$ Clang replaces printf() with putchar() with -O1, and GCC with -O2. I changed the code albeit. \$\endgroup\$
    – Harith
    Commented Jun 15 at 8:04
  • 1
    \$\begingroup\$ @Harith The reason for putc() is just its shorter name (and no format specifier)... Cheers! :-) \$\endgroup\$
    – Fe2O3
    Commented Jun 15 at 8:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.