ANSI Committee's Worst Abuse of C

ANSI委員会のCの最悪の悪用

受賞者:Larry Jones

引用元:https://www.ioccc.org/1990/scjones.c

審査員・作者による説明:https://github.com/ioccc-src/winner/blob/main/1990/scjones.hint

動作

自分自身のソースコードを出力する。いわゆるQuine

$ gcc -ansi -o scjones scjones.c

$ ./scjones > scjones.out

$ diff -s scjones.c scjones.out
Files scjones.c and scjones.out are identical

解説

C89(ANSI C)が規格化したあとの初のIOCCCなので、偏執的にこれに準拠している。 必要とされるヘッダファイルをきちんと#includeし、終了にはexit(EXIT_SUCCESS)などを使う。

そして、悪名高いtrigraphを使っている。 trigraphとは、#の代用として??=と書いたり、[の代用として??(と書いたりできるというC言語の機能のこと。

なぜこのような機能があるかというと、#[などは他の文字と比べて(わずかに)ポータビリティに問題のある文字だったため。 ASCIIではすべて定義されていたが、それを国際化したISO/IEC 646では一部の文字が未定義となっていた。 実際、ISO/IEC 646の日本語版であるJIS X 0201では、バックスラッシュが円マークに置き換えられている。 trigraphを使うと、ポータビリティの高い文字だけでC言語プログラムが書けるようになる。

ということで、この作品はtrigraphを使用しているのでポータブルであるとのこと。 当時の多くのK&R準拠コンパイラでは逆にビルドできない原因になるので、皮肉の意味もあったのかもしれない。 またこの作品は、さらなるポータビリティのために、一行を72文字に抑えている。 これにより、パンチカードで行番号を打つ余裕もある。

IOCCC審査員はscjones.hintでtrigraphへの嫌悪感を隠しておらず、今後の審査ではtrigraphによる難読化はあまり考慮しないとしている。 ASCIIは当時の時点でも既にデファクトスタンダードであり、trigraphは最初から議論のある機能だったことが伺える。

現代のgccはデフォルトでtrigraphを無効化している(-ansiオプションをつけると有効になる)。 このプログラムを-Wallつきでコンパイルすると、皮肉にもtrigraphの使用が警告される。 余談だが、C++17ではtrigraphは廃止されている。

プログラム自体は、普通のQuineだと思う。 実は初のQuine作品の入賞だが、C89規格の話に埋もれていてあまり知られていない。

なお、この作者はANSI委員会でCを規格化したメンバの一人とのこと。 IOCCCの審査は作者情報を見ないで行うので、賞名は作者の正体を知らずにつけたらしい。