1. 「¥n」は、ほんとうは なんと 読まれるの?
1. 画面は「¥n」なのに、プログラムは何を読んでいるのか
1. 画面の「¥n」を、プログラムはなぜバックスラッシュとして読むのか
プログラムの 中の もじれつに「¥n」と 書くと、「ここで 行を かえてね」と いう いみに なります。この ¥ は、日本の がめんでは 円の かたちに 見えます。
でも、コンピュータは かたちを 見て いません。きごうごとに きまった ばんごうを 見て います。「¥」の ばんごうは、もともと バックスラッシュと いう 左へ たおれた 線の きごうの ばんごうです。だから コンピュータには「バックスラッシュと n」と 読めて います。
たとえば、同じ せなかの ばんごうの 子を、日本の みんなは「円さん」と よび、アメリカの みんなは「バックスラッシュさん」と よぶようなものです。ただし 本当は、よび名が ちがうのでは なく、同じ ばんごうを べつの 絵で かいて いるだけです。
C言語などでは、文字列の中のバックスラッシュに特別な役目があります。「\n」と書くと改行、「\\」と2つ重ねるとバックスラッシュそのものを表します[4]。これをエスケープと呼びます。
日本語の画面では、同じ記号が「¥n」のように円の形で見えます。それでもコンパイラは、見た目ではなく文字コード上の番号で判断します。日本語版Windowsの文字コード(コードページ932)では、この番号は0x5Cで、円の形をしていても、C言語のソースではバックスラッシュとして解釈されます。文字コードや処理系によって細かい扱いは異なります[4]。
ファイルの場所を示す「C:¥」も同じです。日本語版Windowsでは円記号の形に見えますが、パス区切りとしての働きは変わらず、変わるのは見た目だけだと、Microsoftの担当者が説明しています[3]。ここでは、円に「変換された」のではなく、同じ番号(0x5C)を円形のフォントで描いている、という関係です。
C言語などの文字列では、バックスラッシュがエスケープ文字として働く。「\n」は改行、「\\」はバックスラッシュ自身を表す[4]。コンパイラが読むのは字形ではなく文字コード上の値なので、コードページ932の環境では、画面で「¥n」と見えていても、C言語のソースではバックスラッシュと n の2文字として解釈される(文字コードや処理系で細かい扱いは異なる)。
この関係は、パスの区切りにも及ぶ。日本語版Windowsが使うコードページ932では、0x5Cが円記号の字形で描かれ、パスも「C:¥」と見える。ところがMicrosoftの担当者の説明では、パス区切りとしての働きは変わらず、変わるのは表示だけである[3]。つまりコードページ932では、「円記号に変換された」のではなく、同じU+005C相当の0x5Cに円形の字形を当てているのであり(一方、JIS X 0201は0x5C自体を円記号と定める。次章)、文字コードとフォントの字形を区別しないと、以後の不具合は説明できない。
では、なぜ同じ番号に、世界の標準と日本の記号が同居することになったのか。
2. どうして 一つの ばんごうに、ふたつの 顔が あるの?
2. 一つの番号に、二つの記号が重なったのはなぜか
2. 同じ0x5Cに、ASCIIのバックスラッシュとJISの円記号が重なった理由
バックスラッシュは、プログラムの ために つくられた 記号では ありません。1961年の 9月、アメリカの IBMと いう 会社の ボブ・ベーマーさんが、「かつ」や「または」を あらわす 記号を、スラッシュと バックスラッシュを 組み合わせて 作りたいと 考えて、文字の なかまに 入れて ほしいと、きまりを 作る 人たちに たのみました。11月には、きまりの 下書きに のりました。
その あと、世界の きまりの 下書きには、国ごとに 自分の おかねの 記号を 入れる ための 場所が ありました。日本は、その 一つに 円の 記号を おきました。1969年の、日本の きまりです。ASCIIが まちがえたのでは なく、あいていた 場所に 円を 入れたのです。
韓国でも、同じ ばんごうに ウォンの 記号が おかれました。
バックスラッシュは、もともとプログラムのエスケープ用に作られた記号ではありません。1961年9月、IBMのボブ・ベーマーは、標準化の委員会に「[」「]」と「\」を加えるよう提案しました。当時のプログラミング言語ALGOLの論理積(∧)と論理和(∨)を、「/\」「\/」と組んで書けるようにするためで、同年11月の会合で草案、のちのASCIIに採用されたと、二次資料は伝えています[1]。エスケープに使う習慣は、あとから広がった用法です。
日本では、1969年に日本向けの規格JIS C 6220(1987年にJIS X 0201へ改称)が制定され、ASCIIでバックスラッシュだった0x5Cに円記号が割り当てられました[2]。二次資料によると、0x5Cは国際規格の草案が各国の通貨記号のために空けておいた位置の一つだったそうです。ASCIIが円記号を間違えたのではなく、日本は用意された枠に円を置いた、と説明されています[2]。
同じことは、他の国にもありました。韓国語版Windowsでは、0x5Cがウォン記号(₩)で表示されます。ドイツ語やスウェーデン語のÖ、デンマーク語やノルウェー語のØ、フランス語のç、スペイン語のÑのように、バックスラッシュが別の字に入れ替わった例もあります。ただ、日本ほど長くは残らなかったと説明されています[1]。
バックスラッシュの出自は、エスケープとは無関係である。1961年9月、IBMのボブ・ベーマーは、標準化の委員会へ「[」「]」「\」の追加を提案し、「\」を「逆除算演算子」と呼んだ。目的は、ALGOLの論理積(∧)と論理和(∨)を、「/\」「\/」と組んで表せるようにすることだった。この提案は同年11月の会合で草案、のちのASCIIに採用された[1]。エスケープとしての用法は、後から広がったものと見られる。
では、なぜその番号に円記号が来たのか。日本は1969年制定の日本向け規格JIS C 6220で、ASCIIでバックスラッシュだった0x5Cに円記号を割り当て、0x7Eのチルダをオーバーライン(上線)にした。この規格は1987年にJIS X 0201へ改称された[2]。二次資料によれば、0x5Cは国際規格の草案が各国の通貨記号などのために空けていた位置の一つで、ASCIIが円を取り違えたのではなく、用意された枠を日本が使ったという。規格本文そのものではなく二次資料による整理である。
同じ構図は、他国にもある。韓国語版Windowsでは0x5Cがウォン記号(₩)で表示され、パス区切りが₩に見える。ISO 646の他の国別版でも、ドイツ語・スウェーデン語のÖ、デンマーク語・ノルウェー語のØ、フランス語のç、スペイン語のÑなど、バックスラッシュが別の字に置き換わった例がある。日本のように長く残った例は、ほかには見当たらない[1]。
こうして0x5Cは、世界では「プログラムのエスケープにもパス区切りにも使われる記号」、日本では「円の絵で描かれる記号」という二つの顔を持った。次に問題になったのは、この二つの顔が、実際のプログラムで何を壊したかである。
3. 見た目と 中身が ずれると、なにが こまるの?
3. 見た目と中身のずれは、どんな困りごとを生んだのか
3. パスの区切りと「ソ」「表」:ずれは現場でどう困りごとになったか
ひとつめは、ファイルの 場所を 書く ときの 区切りです。パソコンの OSの MS-DOSは、区切りに バックスラッシュを えらび、Windowsにも ひきつがれました。なぜ えらんだのかは、はっきりして いません。「/ を ほかの ことに つかって いたからでは」と いう 考えが あります[8]。日本では、これが「C:¥」と 円の かたちで 見えます。
ふたつめは、「ソ」や「表」の ような 字です。ひとつの 字が ふたつの ばんごうで 作られる しくみ(Shift_JIS)では、これらの 字の ふたつめの ばんごうが バックスラッシュと 同じに なります[5]。プログラムが「バックスラッシュだ」と かんちがいすると、字が こわれて 見えます。
見た目だけ 見ても、プログラムの 目から 見ても、まちがいでは ありません。ふたつの 見かたが すれちがう ところで、こまりごとが 生まれたのです。
MS-DOSは、ディレクトリの区切りにバックスラッシュを選び、Windowsに引き継がれました。DOSがコマンドのオプションに「/」を使っていたことが関係したのではないか、という説がありますが、推測の域を出ません[8]。UNIXの区切りは「/」です。
もっと深刻だったのは、日本語の文字が絡む場合です。1982年に実装されたShift_JISでは、「ソ」(0x835C)、「噂」(0x895C)、「表」(0x955C)のように、2バイト目が0x5Cになる文字があると、Wikipediaは整理しています[5]。Shift_JISを想定しない処理系は、この0x5Cをエスケープとして読んでしまいます。その結果、文字列の中の「ソ」や「表」が、別の字に化けたり、字が欠けたりします[5]。
この現象は「ダメ文字」の名で知られています。ここではプログラムの側で何が起きたかに絞りました。文字化けの全体像は、サイトの別の記事「文字化け」で読めます。
MS-DOSはディレクトリの区切りにバックスラッシュを採り、Windowsに引き継がれた。理由は資料で分かれる。DOSがオプション指定に「/」を使っていたためではないか、という推測が@ITの記事にあるが、確かな根拠はない[8]。UNIXが「/」を使うのは対照的である。重要なのは理由よりも結果で、日本語環境のWindowsでは、この区切りが円記号の形で定着した。
より厄介だったのは、Shift_JISとの衝突である。Shift_JISは1982年に実装された2バイト文字の符号で、「ソ」(0x835C)、「噂」(0x895C)、「表」(0x955C)など一部の文字は、2バイト目が0x5Cになる(Wikipediaの整理による)[5]。Shift_JISを想定しない処理系は、1バイトずつ読み進めるため、その0x5Cをバックスラッシュ、すなわちエスケープ文字と判断する。結果として、直後の1文字と合わせて別の意味にとられ、文字が別の字に化けたり欠けたりする。
このとき、プログラムは間違っていない。文字を「1バイトずつの番号」として読む処理系と、「2バイトで一つの文字」と考える日本語環境の間で、読み方がずれただけである。バックスラッシュが円記号の形で見える現象と、同じ根を持つ。なお、同じ0x5Cが文字化けを起こす仕組みは、サイトの別の記事「文字化け」でも扱っている。
では、現場はこのずれにどう対処したのか。
4. こまりごとを、どうやって のりこえたの?
4. 見た目を直すと中身が壊れる:ブラウザと言語の対処
4. 回避策と、WebKitの「見た目を直すと中身が壊れる」例
プログラムを 作る 人は、いくつかの くふうを 使って きました。ひとつは、字の ばんごうの きまりを、バックスラッシュと ぶつからない ものに かえる ことです[5]。もうひとつは、あぶない 字の あとに、目じるしを 入れる ことです。さいごは、字では なく、ばんごうの ならびとして あつかう ことです。
ブラウザ(ネットを 見る ソフト)の WebKitは、見た目を そろえる ために 円の 形に した ところ、コピーや さがす ときに 中身が かわって しまい、ふぐあいが 出ました。そこで、日本語の 文字コードで、しかも 一部の フォントの ときだけに しぼりました[7]。
のちに 世界じゅうで 使う 文字の きまり(Unicode)では、円記号と バックスラッシュに ちがう ばんごうが つきました。それでも Windowsの 日本語フォントは、バックスラッシュの ばんごうを 円の 形で かくので、パソコンに よって 見え方が ことなる ことが あります[6]。
プログラムを書く側には、いくつかの回避策がありました。ソースを0x5Cとぶつかりにくい文字コード(EUC-JPやUTF-8)に変えてから処理する。2バイト目が0x5Cの文字の直後に、エスケープ文字を入れる。文字として扱わず、バイトの数値の並びとして扱う、の三つです[5]。
ブラウザ側の対処は、見た目と中身の板ばさみを教えてくれます。WebKitは、日本語の文字コードで0x5CをU+00A5(円記号)に変換して、見た目をそろえました。ところが、コピーや検索で中身が変わる不具合が出たため、変換を日本語の文字コードと既知のフォントの組み合わせに限る修正が入りました[7]。見た目を直すと、中身が壊れうるのです。
Unicodeでは、円記号(U+00A5)とバックスラッシュ(U+005C)は別の文字です。それでもWindows付属の日本語フォントは、U+005Cを円記号の字形で描きます。そのため、Windowsで作った文書が、macOSやスマートフォンではバックスラッシュに見えることがあります。これには、Unicodeの仕様に反するという意見と、長年の習慣を守るべきだという意見があります[6]。Microsoftが円の表示を残したのは、利用者がなじんでいることと互換性のためとされます[3]。
回避策は大きく三つに分けられる。(1)ソースをEUC-JPやUTF-8のように0x5Cと衝突しない文字コードへ変えてから処理する。(2)2バイト目が0x5Cの文字の直後に、エスケープ文字を挿入する。(3)文字列を文字ではなくバイトの数値配列として扱う[5]。(1)は衝突の原因そのものを避ける方法で、(2)と(3)は、衝突は残したまま読み方のほうを工夫する方法である。
ブラウザの事例は、「見た目を直すと中身が壊れる」を具体的に示す。WebKitは、日本語の文字コードで0x5CをU+00A5(円記号)に変換して、表示をそろえた。ところが、コピーや検索で中身が変わる不具合が出たため、変換を日本語の文字コードと既知のフォントの組み合わせに限る修正(r60063/r60064)が入った[7]。表示を円に合わせた分だけ、中身の扱いにほころびが出たことになる。
Unicodeの側では、円記号(U+00A5)とバックスラッシュ(U+005C)が別の文字として整理された。ところが、Windows付属の日本語フォントはU+005Cを円記号の字形で描画する。一方、macOSやiOSでは両者を区別して表示するため、同じ文書でも環境によって「¥」と「\」に分かれうる[6]。これはUnicodeの仕様から外れるとして賛否がある。Microsoftは、利用者が長年なじんでいることと互換性を理由に、この表示を残したとされる[3]。見た目と中身の分離は、文字の規格が解決しても、フォントという別の層に残った。
ただし、WebKitの修正が現在のすべてのブラウザの挙動を表すわけではない。ここで示したのは一つの事例であり、そこから分かるのは、見た目と中身のどちらを優先しても、何かが犠牲になる、という構造である。
5. じぶんの パソコンで、円の 顔を さがして みよう
5. 自分の画面で、円とバックスラッシュの顔を探してみる
5. 自分の環境で確かめる:フォント、キー、一次資料
おうちの 人と いっしょに、パソコンを 見せて もらって ください。ファイルの 場所(パス)が 書いて ある ところを さがして、区切りの 記号を 見ます。「¥」に 見える パソコンも あれば、「\」に 見える パソコンも あります。ほかの パソコンや タブレットでも 見て、くらべると おもしろいです。
つぎは、「ソ」や「表」が 化ける ぶんしょうを さがすのも、おもしろいかも しれません。このサイトの べつの 記事「文字化け」にも つながります。
家にあるパソコンやスマートフォンがあれば、ファイルの場所(パス)を表示して、区切りの記号を観察できます。「¥」に見える機械と、「\」に見える機械があるかもしれません。同じ文書を別の機械で開き、表示がどう変わるかを比べると、フォントの違いも分かります。使う機械は、家の人に聞いてから選んでください。
「¥」と「\」のどちらに見えたか、メモして友だちとくらべてみると、フォントの違いが見えてきます。さらに深めたいときは、英語ですが、WebKitのバグ報告「24906」に、見た目を直したら何が壊れたのかが開発者の言葉で書かれています[7]。
確かめる方法の一つは、環境ごとの見え方を比べることである。家のパソコンやスマートフォンでパスを表示し、区切りが「¥」か「\」かを調べる。同じ文書を別の端末で開いて見え方が変われば、字形(フォント)の違いが原因である。キーボードの入力は環境で変わるので、まず自分の機械の仕様を確かめてから試す。
原典に当たるなら、WebKitのバグ報告24906が最も具体的である。見た目の修正が何を壊し、どう折り合いをつけたかが記録されている[7]。ベーマーの1961年の提案文書やJIS X 0201の規格本文は、この記事では二次資料を通じて述べた。年号や内容を厳密に確かめたいときは、規格の一次資料に進むとよい。
しらべた もとの じょうほう
参考にした情報源
参考にした情報源と、その使い方
本文で使った資料です。
- Wikipedia: Backslash. https://en.wikipedia.org/wiki/Backslash (ベーマーの提案、他国の置き換え)
- Wikipedia: JIS X 0201. https://en.wikipedia.org/wiki/JIS_X_0201 (JIS C 6220で円記号に置き換えた経緯)
- Michael Kaplan: When is a backslash not a backslash? (2005). https://archives.miloush.net/michkap/archive/2005/09/17/469941.html (コードページ932での表示と中身)
- Wikipedia: バックスラッシュ. https://ja.wikipedia.org/wiki/バックスラッシュ (エスケープ文字としての用法)
- Wikipedia: Shift_JIS. https://ja.wikipedia.org/wiki/Shift_JIS (2バイト目が0x5Cの文字、回避策)
- Wikipedia: 円記号. https://ja.wikipedia.org/wiki/円記号 (Unicodeの分離とフォントの字形)
- WebKit Bugzilla 24906. https://bugs.webkit.org/show_bug.cgi?id=24906 (ブラウザでの見た目と中身の対処)
- @IT: 由来がはっきりしないWindowsの謎仕様. https://atmarkit.itmedia.co.jp/ait/spv/1904/09/news010.html (パス区切りの採用理由に関する推測)
なおした ところ
更新履歴
更新履歴(改版の記録)
- 初版を公開。
このサイトでは、公開した記事の本文は原則として書き直しません。誤りが見つかったときや、内容が古くなったときだけ手を入れ、その理由をこの欄に残します。