UnicodeのUTF-16エンコーディングではほとんどの文字（コードポイント）は2バイトで表現されるが、Unicodeに後から追加収録された文字の多くは4バイトで表現される。4バイト文字がうまく扱えないプログラムというのはわりとよくある。しかし世界中で広く使われるようになった絵文字がよりによって4バイト文字であるせいで、そのような文字が扱えない問題がよいペースで解決に向かいつつある。それについて少し説明してみようと思う。

Unicodeが80年代から90年代初頭にかけてデザインされたときの目標の一つは、Unicodeに含まれる文字数を65536個以内に収めることだった。現代の文章を実用的なレベルで表すためには、漢字などを含めてもそれだけの種類の文字があれば十分だと考えられたのだ。当然これは1文字を2バイトで表すことを念頭に置いていた。つまりコンピュータの揺籃期から当時に至るまで単純に英語のアルファベットを1文字1バイトで表してきたけど、今後はそれを倍に拡張して、すべての言語の文字を2バイトで表そう、という考えがあった。実際の多言語処理はそこまで簡単ではないが、基本的なアイデアとしては素直でよさそうだと言えるだろう。

というわけで1991年にUnicode 1.0が策定されたときには収録された文字は実際に65536個以下であり、UCS-2という2バイト固定長のエンコーディングが規定された。今後はASCIIではなくUCS-2を使ってもらえれば、1文字＝1バイトという考え方を1文字＝2バイトに改めるだけで、多くの言語をサポートできるからね、というわけだ。

90年代前半に、当時新進気鋭のUnicodeを採用するという技術的判断を下したプロジェクトは、この成り行き上UCS-2（のちにはUTF-16）を今でも採用している。たとえばJavaやJavaScript、Windows APIなどがそうだ。



ところがその後65536種類では文字が足りないということが明らかになってきたため、結局2バイト固定長というアイデアは1996年に放棄され、UCS-2はUTF-16として拡張されて、UTF-16は1文字2バイトまたは4バイトの可変長エンコーディングになってしまった。4バイト文字はサロゲートペアと呼ばれる2つの2バイトの符号で表すことになった。

この方針転換のせいで、正直UTF-16は最初から発明されないほうがよかったエンコーディングになってしまった。可変長でよければ、1〜4バイト可変長のUTF-8という扱いやすくてコンパクトなエンコーディングがあるし、どうしても固定長にしたければ、すごく無駄は多くなるけど1文字を常に4バイトで表すUTF-32というエンコーディングがある。UTF-16は無駄が多いけど可変長という両方の欠点を合わせ持つ存在になってしまった。



この結果何が生じたかというと、バグの多いプログラムである。UTF-16を採用したプログラミング言語などでは当然UTF-16を使って文字列を表すことになるが、そこで単純に2バイトで1文字を仮定してプログラムを書くと、サロゲートペアが入力されたときにそれをうまく扱うことができない。ただしそのような文字はUnicodeに後から収録されただけあって、必然的に使用頻度の低い文字ばかりで（日本語でもほとんどの日本人が見たことのないような漢字ばかりだ）、ほとんどの入力に対しては正しく動くので、いつまでも直らないバグになっていた。あるいは最初から問題解決を諦めていて、サロゲートペアの文字を最初から使えないことにしている手抜きシステムもよくあった（MySQLの自称"utf8"エンコーディングなど）。

この状況を変えたのが絵文字だ。2010年に日本の携帯電話との相互運用のためにUnicodeに追加された絵文字は、その後数年で日本語に関係なく世界中で広く使われるようになった。ほとんどの絵文字は他の最近採用された文字と同じくUTF-16では4バイト必要なのだが、どの言語でも極端に利用頻度が高いので、急に世界中の誰もがサロゲートペアについてきちんと考えざるを得なくなった。絵文字のバグを直すと必然的にマイナーな漢字などもきちんと扱えるようになってしまう。これは絵文字の普及の意図せぬ副作用と言えるだろう。

ある意味、ここ数年でコンピュータの歴史上で初めて、英語圏ですらASCIIの範囲内では日常的に文字が足りないという状況になったともいえる。しかもその足りない文字はよりによってUTF-16では処理がトリッキーなサロゲートペアばかりなのである。

また同時に、絵文字などを使うと結局可変長になってしまうのだから、UTF-16ではなく最初からUTF-8を使う方がいいじゃないかという認識が以前より広まったように思う。今では内部処理であれ外部とのデータ交換用であれ、すべての局面でUTF-8を使うのがよいという認識がかなり広まりつつあるが、絵文字の普及がそれを後押ししているならとてもよいことだ。

というわけで、絵文字は後からUnicodeに収録された文字としては異例に利用頻度が高いので、いろいろなシステムにある種のストレステストを強いることになり、結果として世界的にプログラマの認識の改善とプログラムの品質向上に貢献することになったといえる。これはなかなか面白い話だと思う。

