The grand prize in most well-rounded in confusion
もっとも混乱たっぷりの大賞
受賞者:Larry Wall
引用元:https://www.ioccc.org/1986/wall/wall.c
審査員・作者による説明:https://www.ioccc.org/1986/wall/hint.html
動作
“Dvorak Keyboard Emulator”と表示した後、入力文字列をそのままエコーするだけのプログラム。
Ctrl-Dで終了。
$ gcc -traditional-cpp -o wall wall.c
$ ./wall
Dvorak Keyboard Emulator
Hello
解説
ネタの理解にあまり自信がない。
Cコンパイラの警告を踏まえるとネタがわかるっぽい記述がhint.textにある(”(the author) asks you to compile and consider the warning message generated by the C compiler.”)。
現代のコンパイラでは大量に警告が出てしまうのでどれを指しているかわかりにくいが、おそらく、#define keyboard ...
が2回行われているので、warning: "keyboard" redefined
という感じの警告は当時も出ていたのでは無いかと思われる。
「キーボードが再定義された」ということで、Dvorak配列と言ってみた、という洒落だろうか。
なお、このプログラムはとくにQwerty→Dvorak変換をするようなことはしない。
このコードは当時のCプリプロセッサの微妙な挙動に全力で依存しているので-traditional-cpp
が必要。まず
#define _O(s)s
#define C_(sand)_O(sand)witch
C_(s)
がswitch
キーワードになることを期待しているが、残念ながら現代のC仕様ではs witch
になる(1つ以上のスペースが入る)ので動かない。
同様の方法でsystem
関数の呼び出しも隠している(怖い)。
それから
#define c_(cc)c cc=
c_(+)o[...];
はc+=o[...];
になることを期待しているが、これも-traditional-cpp
がなければ動かない。
パッチとしては、文字列リテラルの破壊的変更があるのでstrdup
を2箇所ほど入れる必要がある。
これで一応動くようになった。
その他の難読化としては、整数を素直に書かない(文字リテラルや__LINE__
や8進数リテラルなどを駆使している)、system関数にわたすコマンド文字列を暗号化している、わかりにくいマクロで誤読を誘う(main
というマクロとか)など。
メインの挙動は、stty raw -echo
をsystem
で呼んで端末の生入力を受け取るようにし、改行とDEL文字とCtrl-Dを特別扱いする以外は入力をそのまま出力するだけ。
ちなみにこれの作者はPerlの作者であるラリー・ウォール。
ただし入賞当時はまだPerl誕生の2年前で、hint.textでは「patchとrnの作者」として言及されている。
clangでビルドするには-Wno-return-type
が必要。
パッチ
パッチをダウンロード