I came across this tricky question a few weeks ago.

Write a small C program, which while compiling takes another program from input terminal, and on running gives the result for the second program. (NOTE: The key is, think UNIX).

At first, it looked like a strange puzzle. How can a C code force the compiler to request for input while it is already compiling the code? After a little thinking, the solution became obvious. I assumed that the compiler is allowed to accept the input during the preprocessing step.

The preprocessor allows us to direct the compiler to include another file with the #include directive. So, why not use it to read the standard input?

So, the solution has only one line of code: #include "/dev/stdin". On Windows machine, CON represents the standard input, so: #include "CON"

andromeda:/home/susam# cat reader.c
#include "/dev/stdin"
andromeda:/home/susam# gcc -o reader reader.c
#include <stdio.h>

int main(int argc, char **argv)
{
    printf("hello, world\n");
    return 0;
}
andromeda:/home/susam# ./reader
hello, world

11 comments

Vallabha said:

Very simple and very neat solution. Yet another complex puzzle with a simple solution. :)

Sharath said:

Thanks. It was bugging my head for long.

Shaffu said:

Hi. I am not able to terminate the program compilation, when does it stop taking the input and when will the executable ./reader will be created? I am trying it in my Red Hat Linux machine?

Susam Pal said:

Shaffu,

You need to press Ctrl + D to indicate termination of input stream. Note that you need to press Ctrl + D while you are on a blank line. So, you would press Enter first to move to the next blank line and then press Ctrl + D.

Once you end the input stream by pressing Ctrl + D, gcc would compile the code and create the executable.

Shaffu said:

Thanks Susam. It's working!

Hunter said:

Compile-time generated C source code. This is scary :D

Sam said:

I am not sure how closely it fits the overall idea behind this puzzle, but you can also use a [bash] here-file to accomplish this.

sam@box$ ls
sam@box$ gcc -x c - << EOF
> #include <stdio.h>
> int main(int argc, char *argv[]) {
>   printf("Hi planet!\n");
>   return 0;
> }
> EOF
sam@box$ ls
a.out
sam@box$ ./a.out
Hi planet!
sam@box$

Razee Marikar said:

Hey, this is spinellis' entry for the IOCCC, submitted on 1988. See http://www.ioccc.org/years-spoiler.html, search for spinellis. It's under 1988.

Susam Pal said:

Razee,

Thank you for the URL. It indeed seems like a very old puzzle. I came across it for the first time in an internal blog at my workplace.

Post a comment

RSS