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 -echosystemで呼んで端末の生入力を受け取るようにし、改行とDEL文字とCtrl-Dを特別扱いする以外は入力をそのまま出力するだけ。

ちなみにこれの作者はPerlの作者であるラリー・ウォール。 ただし入賞当時はまだPerl誕生の2年前で、hint.textでは「patchとrnの作者」として言及されている。

clangでビルドするには-Wno-return-typeが必要。

パッチ

パッチをダウンロード