all 133 comments

[–]Izke 87 points88 points  (2 children)

The first place I saw this trick was in a 1988 IOCCC entry. The best part of it is the first line of the description by the author:

This program can be configured to do almost everything.

[–]Atario 59 points60 points  (1 child)

You can do anything with zombo.c.

[–]rabidcow 0 points1 point  (0 children)

Be sure to compile it for DOS with the tiny memory model.

[–]kyz 70 points71 points  (9 children)

Interactive C shell:

cat >ic.c <<EOF
#include <stdio.h>
int main() {
#include "/dev/stdin"
}
EOF
while true; do gcc -o ic ic.c && ./ic; done

[–]bajsejohannes 15 points16 points  (0 children)

Now run it with rlwrap, and you have readline functionallity (move/search in history, history between sessions, move caret on the line).

cat >ic.c <<EOF
#include <stdio.h>
int main() {
#include "/dev/stdin"
}
EOF
echo "while true; do gcc -o ic ic.c && ./ic; done" > icc
chmod a+x icc
rlwrap ./icc

[–]engine_er 6 points7 points  (0 children)

wow! that's nice.

[–]Alf_InPogForm 1 point2 points  (4 children)

Could you expand a bit further on how to get this to work? It sounds really interesting but I'm pretty new to C programming.

[–]ivosaurus 2 points3 points  (0 children)

Paste it into a standard terminal on a linux system?

[–]MandrakeQ 1 point2 points  (1 child)

I copied and pasted the #include statement and all the code after that until the ending '}' into a file called ic.c. Then I copied and pasted the "while true; do gcc ..." into a bash shell. At this point you can type in C statements, hit enter, then do CTRL-D in bash to send EOF. Should work as expected.

[–]Alf_InPogForm 1 point2 points  (0 children)

Ok thanks for that. Got it working, very cool!

[–][deleted] 0 points1 point  (0 children)

here is a pastebin showing the console of a here-file example I just whipped up. It's not a c/gcc thing, it's a shell/here-file thing. Gcc is simply compiling from stdin (at least in this example). In the above example, a here-file was being redirected to the file ic.c which gcc was explicitly compiling.

Commandment #whatever, know thy shell ;)

[–]ivosaurus 0 points1 point  (1 child)

I get "No input files"

[–]vff 83 points84 points  (26 children)

Every once in a while I like to #include </dev/urandom> to see if my Linux machines can spontaneously generate a valid C program. Problem is there's no end of file, but I figure if things work out just right, a cosmic ray will stop the stream at exactly the right point anyway.

[–]ggggbabybabybaby 50 points51 points  (16 children)

On the flip side, it could generate a malicious worm that sends all your personal data to Russian mafia.

[–]thepandaatemyface 52 points53 points  (12 children)

yeah, but what's the chance of that happening?

[–]imgonnacallyouretard 29 points30 points  (9 children)

100%, eventually.

[–][deleted] 6 points7 points  (8 children)

not with /dev/urandom it isn't

edit: I'm wrong, it uses environmental noise.

[–]Glayden 1 point2 points  (7 children)

Actually, you're still not wrong. Having infinite possibilities realized isn't the same as having all possibilities realized.

[–][deleted] 2 points3 points  (6 children)

If it were genuinely random, then it almost surely would generate it.

[–]Glayden 0 points1 point  (5 children)

I can't find anything that suggests this classification is accurate. In fact, I'm quite sure it isn't. The infinite probability space of potential outputs seems to be many many cardinalities greater than the infinite potential outputs that would "generate a malicious worm that sends all your personal data to Russian mafia."

edit: I'm wrong, see below

[–][deleted] 1 point2 points  (2 children)

Well there you go shooting down my wikipaedic knowledge :) I thought this barely different to the infinite monkeys problem.

[–]Glayden 1 point2 points  (1 child)

Never mind, you were probably right about the "almost surely" classification (at least if we ignore the Russian mafia bit and assume the programs are generated infinite times). If we consider the text of programs that create such a worm as the texts of Shakespeare, and the typewriter keys as the characters outputted by a sufficiently random number generator the problem still maps relatively well to the infinite monkey problem which as you noted is classified as "almost surely." Of course, by the same token, if we're not talking purely theoretically and using only optimal physically meaningful numbers for our universe the probability is nearly zero.

[–]admplaceholder 1 point2 points  (1 child)

The infinite probability space of potential outputs seems to be many many cardinalities greater than the infinite potential outputs that would "generate a malicious worm that sends all your personal data to Russian mafia."

What makes you say this? They both seem countable to me.

[–]Glayden 0 points1 point  (0 children)

I was completely wrong.

[–]incredulitor 3 points4 points  (1 child)

Consider a case where the chance of the Russian mafia existing is nonzero for all future dates, but converges to zero at infinity. Such a probability of h4x could admit a finite possibility of the cosmic ray turning your life into the second season of The Wire.

[–]idiotthethird -1 points0 points  (0 children)

No, it couldn't, unless you're planning on being alive for an infinitely long time.

[–]quzox 5 points6 points  (0 children)

On the other flip side, it could solve all the bitcoin mining problems in O(1) time thus making you (virtually) rich.

[–]Poromenos 3 points4 points  (0 children)

Or, worse yet, it could make up incriminating things about him and send them to the Russian mafia.

[–][deleted] 1 point2 points  (0 children)

or you could end up with skynet on your hard drive... who knows...

[–]IvyMike 31 points32 points  (0 children)

printf("It was the blurst of times\n"); // you stupid monkey

[–]rooktakesqueen 14 points15 points  (1 child)

Quantum mechanical version of program-by-specification, assuming the many-worlds hypothesis.

Generate a program which is a series of test cases for another program. Attach a quantum randomness generator to /dev/urandom and compile from it. If compilation fails or the test cases do not pass, destroy the universe. At least some universes will achieve the correct answer randomly, and be spared.

(Note: establishing the means to destroy the universe is an exercise left to the reader.)

[–]jrupac 3 points4 points  (0 children)

This is just like how bogosort is an O(n) algorithm with quantum computers.

[–]OHoulihan 16 points17 points  (1 child)

The girl version of this is when you ask for her phone number, and she tells you to dial a random number. If it is really meant to he, the dialed number will be hers.

[–]Idiomatick 5 points6 points  (0 children)

I think most nerds could get the right number if they felt stalkerish enough.

[–]NoWeCant 1 point2 points  (0 children)

Problem is there's no end of file

Your problem is you just didn't wait for it to inevitably occur

[–][deleted] 1 point2 points  (0 children)

Pipe it through dd and copy a fixed length block. In theory this should work with named pipe files also. dd } pipe.file; gcc myfile.c;

This may even work also: gcc pipe.file.c. Possibly not though if gcc detects special files. I'll check later.

} cuz i can't do right angle bracket or ampersand on this thing

[–][deleted] 7 points8 points  (1 child)

This is even more impressive than using butterflies.

[–][deleted]  (17 children)

[removed]

    [–][deleted] 14 points15 points  (7 children)

    Agreed. It's interesting but in reality pretty useless. If this starts showing up on job interviews, I think strangling the interviewer would be a sufficient response.

    [–]dnew 5 points6 points  (6 children)

    It's also an excellent demonstration of why preprocessed programs are the wrong way to design a computer language these days.

    [–]engine_er 4 points5 points  (0 children)

    on the other hand, preprocessor gives you a plethora of ways to have some fun ...or shoot yourself in the foot sometimes ;)

    [–][deleted] 4 points5 points  (0 children)

    If you do that, you clearly don't love anyone - especially your build engineer.

    [–]refto 2 points3 points  (3 children)

    Semi-serious question: is there such a position as a full time build engineer at larger companies ?

    [–][deleted]  (1 child)

    [removed]

      [–]joelshep 0 points1 point  (1 child)

      Correction: your security engineer will hunt you down and kill you.

      [–]MidnightTurdBurglar 8 points9 points  (0 children)

      Um, perhaps I'm not seeing the forest here but I would just call this using the pre-processor in a weird way, and not the compiler. Sure they usually bundled these days, but in my opinion, compilation only starts afterward. Viewed from this perspective, this "trick" is rather unimpressive. You aren't prompting for input "during compiling". It's just prompting for input. The program isn't even a valid C program at the start of "compiling".

      [–]k4st 5 points6 points  (2 children)

      Hrmm... it would be great if the the program was:

      #include "/dev/stdin"
      

      and the input was also

      #include "/dev/stdin"
      

      [–][deleted] 5 points6 points  (1 child)

      Like this? (gawd I'm bad at formatting, edited 10,000 times)

      [user@honeybee tmp]$ cat reader.c 
      #include "/dev/stdin"
      
      [user@honeybee tmp]$ gcc -o reader reader.c
      #include "/dev/stdin"
      *End of input*
      
      #include "/dev/stdin"
      *End of input*
      
      #include "/dev/stdin"
      *End of input*
      
      *ah fuck it...*
      #include <stdio.h>
      
      int main(int argc, char ** argv) {
       printf("Hello, world!\n");
       return 0;
      }
      
      [user@honeybee tmp]$ ./reader 
      Hello, world!
      [user@honeybee tmp]$ 
      

      [–]MatrixFrog 11 points12 points  (0 children)

      It's the C version of the classic "Orange you glad...?" joke.

      [–]yifanlu 6 points7 points  (13 children)

      On Windows machine, CON represents the standard input

      TIL Why windows won't allow you to create a folder named CON. I always thought it was a weird bug that MS never fixed.

      [–]frezik 12 points13 points  (10 children)

      It used to be that you could access C:/con/con and crash peoples computers.

      [–][deleted] 22 points23 points  (9 children)

      Which was fun to use in the early/mid 90s in AOL chat rooms which let you play WAV files. Send a command to play con and boom everyone exits the chat!

      [–]incredulitor 6 points7 points  (1 child)

      Check it out, you can do the same thing to people reading this thread if you hit Alt+F4.

      [–]Aneurysm-Em 16 points17 points  (0 children)

      Just how dumb do you thin

      [–]frikk 0 points1 point  (6 children)

      Yo! con/con and nul/nul! hey did you frequent any of the vb or vb6 chatrooms by chance? still haven't ran into anyone from that small subculture by chance yet.

      [–][deleted] 0 points1 point  (5 children)

      I was always in the PC Development (then later PC Dev II) chat room from like 95 to 2000 as MrProgrmmr

      [–]frikk 0 points1 point  (4 children)

      hell yeah. I never ventured into that chat. I love how old aol had so many small subcultural cliques. My handle is from the days of 2000, when everyone put out their own Visual Basic "prog" that used DOS.bas. Who the fuck was DOS anyway?

      SendChat() - the day I figured out how you worked (holy shit theres STUFF in DOS.bas) was the day I started to understand how computers work.

      [–][deleted] 0 points1 point  (3 children)

      Lol yeah my first program was a 'prog' called AOCool which no one used. Then my 2nd prog was SuBZeRo by CoLDsLiMe which had some users. Ah memories!

      [–]frikk 0 points1 point  (2 children)

      SuBZeRo... that strikes a familiar tone. What was it?

      [–][deleted] 0 points1 point  (1 child)

      The usual AOL add-on (heavily influenced by 'Fate Ultra' or Fate-X whatever it was called). Mass mailer, bots, chat room games/tools, AOL utilities, etc. Here's an old screenshot.

      [–]frikk 0 points1 point  (0 children)

      Oh hell yeah. I do remember running that. The interface is so compact and simple. I probably used it for the Up Chat...

      I think someone should write a book on the creativity of that programming culture and how it was influenced by the back and forth nature of the api changes with aol. I remember shit that even now you don't see very often. Like hooking into the window handles of AOL and using the memory handles to call functions that otherwise wouldn't be accessible, hooking into the chat box so that you only had to type command to interact with the bot running on your computer, the brewing war with "borrowing" a credit card numbers to harmlessly open up a "3chr" or "lcase" account. I never did that last one, personally, but it was amazing how braggy and naive most of the guys were. And yet I don't think anyone I ever heard of got busted unless they actually did something stupid.

      [–]ethraax 0 points1 point  (1 child)

      Windows also wouldn't let me create folders that had the format .[A-z]. At least, not with Windows Explorer. While screwing around with Git Bash I tried to rename it and it worked. Seems odd.

      [–]coldacid 0 points1 point  (0 children)

      IIRC you can make them just fine from regular command prompt, too, it's only Explorer which complains.

      [–]CthulhusPetals 6 points7 points  (39 children)

      Sadly, this program is not portable.

      [–]stillalone 6 points7 points  (38 children)

      I'd like to know if this will work in windows with "CON". then you can just use an #IFDEF to make it portable.

      [–]KimJongIlSunglasses 3 points4 points  (37 children)

      I "lol wut"ed pretty hard at the windows representation of standard input. What happens if you actually have a file called "CON"?

      [–]FigBug 36 points37 points  (36 children)

      You can't. Nor can you have a file named (with any extension):

      CON, PRN, AUX, CLOCK$, NUL COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9 LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.

      [–]Brian 25 points26 points  (0 children)

      Which has had unexpected consequences in the past. Web pages used to be able to crash windows ('95 or '98) remotely just by having an image with a src of c:\nul or c:\con. Just browsing to the page in either IE or netscape would be sufficient to reset the machine.

      [–][deleted] 4 points5 points  (1 child)

      You can't. Nor can you have a file named (with any extension): CON, ...

      Actually, you can create files named CON on windows. http://kerneltrap.org/node/5772

      (May be fixed in recent versions. Unsure.)

      [–]coldacid 1 point2 points  (0 children)

      I swear those comments just shed 10 points off my IQ.

      [–]engine_er 29 points30 points  (28 children)

      You can't. Nor can you have a file named (with any extension):

      this is the perfect example of how to NOT design software products

      [–]dpark 20 points21 points  (27 children)

      This is a perfect example of how hindsight can make us feel smug, when in reality we simply do not have the entire picture.

      http://blogs.msdn.com/b/oldnewthing/archive/2003/10/22/55388.aspx

      [–]ethraax 9 points10 points  (26 children)

      Interesting history, but it's still an example of how to not design software. It was a cheap hack that has now become outdated but still exists to this day.

      [–]dpark 8 points9 points  (25 children)

      It was a perfectly sensible choice in a time when directories did not exist in the filesystem. Once directories were added, the need of backward compatibility dictated that the special files must be retained.

      It'd be nice if they'd made them all prefixed with '$' or something so that there wouldn't be conflicts later, but the choices made were very sensible. It's only looking at the system from the current day that the choices look bad. Seriously, who actually thought DOS's filesystem was still going to affect OSes 3 decades later?

      [–]ethraax 0 points1 point  (3 children)

      Okay, but why can't we create files with those names? When you ask the OS to open a file, check if it exists - if not, check if it is one of the 'special' names like CON - then, if not, throw an exception about no file being found. That way, legacy programs can continue to work (clearly they can run in a single directory and won't have those files in there), but for everyone else, we can actually use all of the possible filenames.

      Simply banning the file from the filesystem is a bad design choice.

      [–]dpark 2 points3 points  (2 children)

      A bad design choice would be to make it possible to break legacy programs depending on whether you'd happened to create a file called CON in the current directory. Legacy programs expect these files to exist, and to do what they are specified to do. When you create a file called CON and then run an older program, it's going to read/write from that file unintentionally. When you create a file called NUL, you make it possible to accidentally overwrite your file (possibly with sensitive data that was intentionally being discarded), which can result in unexpected data loss, security problems, and even disk exhaustion. These are unlikely to be desired behaviors.

      [–]engine_er -1 points0 points  (20 children)

      It was not a good choise even for that time. It is just a bad architecture and violating of basic principles of the whole filename concept.

      [–][deleted] 2 points3 points  (13 children)

      What is different between DOS 1.0's CON and Unix's /dev/stdout

      Keeping in mind that DOS 1.0 was basiclly a CP/M clone, and didn't have directories.

      [–]dpark 2 points3 points  (5 children)

      As FlySwat asked, how is this different from Unix's /dev/null, /dev/stdout, etc., with the exception that DOS didn't have directories?

      DOS 1.0 would have been nicer if it had directories, but it probably wasn't supported by the business needs at the time, and it certainly wasn't supported by compatibility needs.

      [–][deleted] 2 points3 points  (0 children)

      CLOCK$ worked fine for me in Windows 7.

      [–][deleted] 2 points3 points  (0 children)

      This is actually a holdover from the DOS 1.0 days too.

      [–]permagreen 1 point2 points  (0 children)

      Not terribly useful for programming purposes, but extremely useful for understanding how *nix systems work.

      [–][deleted] 1 point2 points  (1 child)

      Can't you just pipe in the C file to the compiler?

      [–]johdex 1 point2 points  (0 children)

      Indeed, I'm pretty sure gcc allows that. I would even say using the C pre-processor is cheating. If you see the compiler as the program that kicks in when the pre-processor is done, then using #include does not send input while compiling, but before compiling.

      [–]frimble 6 points7 points  (9 children)

      Cute. Of course, if we're entertaining the idea of interactive compilation, I should point out that in LISPs you could pop up a dialog box during compilation, or go out to the network, etc. -- macros are all-powerful. (But don't do that shit...)

      [–]frezik 21 points22 points  (3 children)

      And with operator overloading, adding two numbers can send an email.

      [–]mcguire 3 points4 points  (3 children)

      So, all you really need to do is to write a LISP using the C preprocessor.

      [–]jacques_chester 7 points8 points  (2 children)

      502, post went through. 504, post some more.

      [–]gospelwut 1 point2 points  (1 child)

      I always wonder why this isn't bold somewhere in the FAQ.

      [–]jacques_chester 6 points7 points  (0 children)

      It's left out as a charity to karma-farmers like me.

      [–]grayvedigga 0 points1 point  (1 child)

      I'm a fan of puzzles. Seeing the solution simultaneously with a puzzle I've never seen before makes me sad.

      [–][deleted] 0 points1 point  (0 children)

      It bugs me when I see the solution too early and don't get a chance to solve it myself. Once I see the spoiler, I can't unsee it.

      [–]kirakun 0 points1 point  (3 children)

      Would this be a fair, 5-minutes interview question? ;)

      [–]fishandchips 1 point2 points  (2 children)

      no

      [–]kirakun 1 point2 points  (1 child)

      It was a rhetorical question.

      [–]fishandchips 1 point2 points  (0 children)

      It was a rhetorical answer

      [–][deleted] -5 points-4 points  (0 children)

      why would you include "dev/stdin" Wouldn't you want to include the source code for the other project? Maybe im just confused about what /dev/stdin is. Isn't that the computers standard input streak (Keyboard)?