Geoffrey Zoref
3 min readOct 21, 2019

Worst abuse of the C preprocessor (IOCCC winner, 1986)

Above is a mess of compilation errors when I tried to compile the following code:

#define DIT (
#define DAH )
#define __DAH ++
#define DITDAH *
#define DAHDIT for
#define DIT_DAH malloc
#define DAH_DIT gets
#define _DAHDIT char
_DAHDIT _DAH_[]="ETIANMSURWDKGOHVFaLaPJBXCYZQb54a3d2f16g7c8a90l?e'b.s;i,d:"
;main DIT DAH{_DAHDIT
DITDAH _DIT,DITDAH DAH_,DITDAH DIT_,
DITDAH _DIT_,DITDAH DIT_DAH DIT
DAH,DITDAH DAH_DIT DIT DAH;DAHDIT
DIT _DIT=DIT_DAH DIT 81 DAH,DIT_=_DIT
__DAH;_DIT==DAH_DIT DIT _DIT DAH;__DIT
DIT'\n'DAH DAH DAHDIT DIT DAH_=_DIT;DITDAH
DAH_;__DIT DIT DITDAH
_DIT_?_DAH DIT DITDAH DIT_ DAH:'?'DAH,__DIT
DIT' 'DAH,DAH_ __DAH DAH DAHDIT DIT
DITDAH DIT_=2,_DIT_=_DAH_; DITDAH _DIT_&&DIT
DITDAH _DIT_!=DIT DITDAH DAH_>='a'? DITDAH
DAH_&223:DITDAH DAH_ DAH DAH; DIT
DITDAH DIT_ DAH __DAH,_DIT_ __DAH DAH
DITDAH DIT_+= DIT DITDAH _DIT_>='a'? DITDAH _DIT_-'a':0
DAH;}_DAH DIT DIT_ DAH{ __DIT DIT
DIT_>3?_DAH DIT DIT_>>1 DAH:'\0'DAH;return
DIT_&1?'-':'.';}__DIT DIT DIT_ DAH _DAHDIT
DIT_;{DIT void DAH write DIT 1,&DIT_,1 DAH;}

This C file, which uses the preprocessor’s #define function, is quite the disaster. This mess comes from the winner of the 3rd International Obfuscated C Code Contest of 1986, a famous contest that rewards contestants who create the most confusing, pointlessly unreadable and unfriendly C code possible.

Despite the compiler’s attempt to shame the programmer with its multiple errors and warnings, the code does successfully compiles as a Morris Code converter!

That’s pretty cool, but how does this unreadable mess of a C file translate ASCII text to Morris Code? Lets shake it up and see what we can infer by de-obfuscating the code.

We can clean the original C file up using the -E flag when compiling:

gcc -E hague.c -o hague

This has taken out all unnecessary background noise, but it’s still not the worlds cleanest looking code. Not by a long-shot!

Compilation stopped at the preprocessor stage

Notice that we now have main, gets, for and other friendly and recognizable pieces of C syntax. Lets neaten it up a bit:

Some more…
OK, not bad

It’s still not Betty compliant, but now this looks like a C file! We have a main() opening, a char pointer *_DIT, *DAH_, which are like Dot and Dash of Morris Code. There is a malloc, a nested for loop, a gets function and other recognizable C syntax.

It’s pretty obvious that with even more organisation, this could look like a sane and rational C file, one not obfuscated enough to win a contest!

Tadda!!!