This reminds me of "A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux" [1]. The author tries to create the smallest possible elf executable possible. You would think it'd be easy... :) go read it. Very cool!<p>[1] <a href="http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html" rel="nofollow">http://www.muppetlabs.com/~breadbox/software/tiny/teensy.htm...</a>
It depends on the definition. You can do better than this if you define a valid C program as anything that passes though the C compiler and generates an executable. Behold the zero length program:<p>$ touch a.c<p>$ gcc -c a.c<p>$ ld a.o<p>ld: warning: cannot find entry symbol _start; defaulting to 0000000000400078<p>$ ./a.out<p>Segmentation fault
The explanation is not quite correct - execution starts at &main rather than the address given by the value of main. On VC++, at least - well, on my PC anyway - the process halts because the data segment doesn't have the execute bit set. It isn't trying to run code at address 0.<p>(If execution of bytes in the data segment were possible, which I'm sure it used to be, then you'd still likely get a crash, but it's not guaranteed. (uint32_t)0 is a valid sequence of instructions - it's ADD BYTE PTR [EAX],AL - and so if EAX contained a valid value then it would execute without a problem. Then, if the following byte were 0xC3 (RET) then the program would execute. OK, so that's all rather unlikely, but you have to bear these things in mind. So I think 0xCC (INT 3) would be a better choice.)
Who says it will crash? Could run very nicely, printing a list of prime numbers, or write poetry, or anything else that undefined behaviour encompasses.
It seems to be down, google cache: <a href="http://webcache.googleusercontent.com/search?q=cache:4FhUcns72Z4J:llbit.se/%3Fp%3D1744+&cd=1&hl=es-419&ct=clnk&gl=ar" rel="nofollow">http://webcache.googleusercontent.com/search?q=cache:4FhUcns...</a>
The first IOCCC winner declared main as a short[] of VAX machine code: <a href="http://www.ioccc.org/1984/mullender.c" rel="nofollow">http://www.ioccc.org/1984/mullender.c</a><p>You could probably do the same thing in x86 and it'd work on a modern compiler.
> Also, global variables in C are initialized to zero implicitly, so this is equivalent:<p>EDIT: <i>this</i> is wrong, see below.<p>That's wrong. 'static' variables are initialized to zero. Non-static variables are un-initialized, so they have a "random" value.<p>See:<p>$ valgrind ./a.out<p>==5118== Memcheck, a memory error detector<p>==5118== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.<p>==5118== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info<p>==5118== Command: ./a.out<p>==5118==<p>==5118==<p>==5118== Process terminating with default action of signal 11
(SIGSEGV)<p>==5118== Bad permissions for mapped region at address 0x600864<p>==5118== at 0x600864: ??? (in /home/def/a.out)<p>==5118== by 0x4E54A14: (below main) (in /usr/lib/libc-2.17.so)
I'm not convinced this is a C89 program. It is only an "accident" that the linker doesn't know about types.<p>I find it hard to believe that the C89 spec states that an integer called "main" is to be considered the main function, and suspect this is undefined behaviour (though I've not checked).
"address 0, which is not an address that we have access to"<p>if I'm not mistaken, there are platforms like TI C600 dsps for which 0 is the start of the usable address space