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の審査は作者情報を見ないで行うので、賞名は作者の正体を知らずにつけたらしい。