CロケールがASCIIではなくUTF-8の場合、何が壊れますか?

CロケールはASCII文字セットを使用するように定義されており、POSIXはロケールを変更せずに文字セットを使用する方法を提供していません。

代わりにCのエンコーディングをUTF-8に切り替えるとどうなりますか?

プラス面は、UTF-8が、システムデーモンを含め、すべてのプロセスのデフォルトの文字セットになることです。明らかに、Cが7ビットASCIIを使用していると想定しているため、壊れてしまうアプリケーションがあります。しかし、これらのアプリケーションは本当に存在しますか?現在、記述されたコードの多くはある程度ロケールと文字セットを認識していますが、7ビットのクリーンな入力のみを処理でき 、受け入れるように簡単に適応できないコードを見ると驚きます。 UTF-8対応のC。

コメント

  • 2009年のこのスレッド UTF-8ベースのCロケールの必要性について説明していますが、POSIXの破損の問題には対処していません。
  • FWIW、OpenBSDにはC.UTF-8ロケールがあります。また、POSIX.UTF-8

回答

Cロケールデフォルトのロケールではありません。これは、「驚くべき」動作を引き起こさないことが保証されているロケールです。多くのコマンドには、保証された形式の出力があります(たとえば、psまたはdfヘッダー、date format)CまたはPOSIXロケール。エンコーディング(LC_CTYPE)の場合、[:alpha:]にはASCII文字のみが含まれることが保証されています。 Cロケールが変更された場合、これにより多くのアプリケーションが誤動作するようになります。たとえば、無効なUTF-8の入力をバイナリデータとして扱うのではなく拒否する場合があります。

システム上のすべてのプログラムでUTF-8を使用する場合は、デフォルトのロケールをUTF-8に設定します。 。つまり、単一のエンコーディングを操作するすべてのプログラム。一部のプログラムはバイトストリームのみを操作し、エンコーディングを気にしません。一部のプログラムは複数のエンコーディングを操作し、ロケールを気にしません(たとえば、WebサーバーまたはWebクライアントはヘッダー内の各接続のエンコーディングを設定または読み取ります)。

回答

少し混乱していると思います。 「Cロケール」は他のロケールと同じで、ご指摘のとおり、従来は7ビットASCIIの同義語です。

Cライブラリに組み込まれているので、ライブラリにはある種のフォールバックがあります-ロケールはあり得ません。

ただし、これは、Cコードから構築されたプログラムが入力を処理する方法とは関係ありません。ロケールは、実行可能ファイルに渡される入力を変換するために使用されます。 システムロケールがUTF-8の場合、UTF-8は、ソースがCで記述されているかどうかに関係なく、プログラムが取得するものです。そうしないと。したがって:

7ビットのクリーンな入力しか処理できず、UTF-8を受け入れるように簡単に適応できないコードを見ると驚きます-有効なC

あまり意味がありません。標準入力から読み取る標準Cソースの最小限の部分は、システムからバイトのストリームを受信します。システムがUTF-8を使用し、一部のHIDハードウェアからストリームを生成した場合、そのストリームにはUTF-8でエンコードされた文字が含まれている可能性があります。他の場所(ネットワーク、ファイルなど)からのものである場合は、何かが含まれている可能性があります。これにより、UTF-8標準の仮定が役立ちます。

CロケールがUTF-8ロケールよりもはるかに制限された文字セットであるという事実は無関係です。これは単に「Cロケール」と呼ばれますが、実際には、Cコードの作成とはほとんど関係がありません。

実際、UTF-8文字をcにハードコーディングできます。 -ソース内の文字列。システムがUTF-8であると仮定すると、これらの文字列は、結果の実行可能ファイルで使用されたときに正しく表示されます。

コメントに投稿した「RogerLeigh」リンクは、拡張セット(UTF-8) は、組み込み環境向けのCライブラリ内のCロケールであるため、システムで処理するために他のロケールをロードする必要はありません。 UTF-8。

「CロケールがASCIIではなくUTF-8だった場合、何が壊れるのでしょうか?」という質問に対する答えは、推測、何もありません。しかし、組み込み環境などの外では、これを行う必要はあまりありません。しかし、GNU Cなどのライブラリのある時点で標準になる可能性が非常に高いです(そうなる可能性もあると思います)。

コメント

  • さまざまなsyscallの動作が影響を受けるロケールの文字セットによって、たとえば« isupper()はA-umlaut(Ä)デフォルトのCロケールでは大文字として。»( man7.org/linux/man-pages/からman3 / isprint.3.html )。isprint()は、CがASCIIのみとして定義されているという事実によっても影響を受ける別のシステムコールです。
  • はい、(理論的には)これらはロケールですが、そのロケールは通常UTF-8であり、必ずしも' C ' である必要はありません。 GNUでは、'この点で壊れています: gnu.org/software/gnulib/manual/html_node/isupper。 html UNIXシステムの基本は100%Cでコーディングされているため、" Cは' tハンドルUTF-8 "は問題ありませんが、明らかに正しくありません。 Cで記述されたプログラムがUTF-8を処理できない場合、システム上に' UTF-8は存在しません。期間。
  • Qv。また、POSIX isupper()ページ pubs.opengroup.org/onlinepubs/9699919799/functions/isupper.html "プロセスの現在のロケール "ではなく、" Cロケール"。これはISO標準にもあり、Cロケールの" " および "現在のロケール"、通常は "の形式(現在のロケールがCロケール" など。Linuxを使用している場合は、GNU C 'の実装に注意してください。一部のctype関数の一部が壊れています。
  • @gioeleこれらはライブラリ関数であり、syscallではありません。システムコールはカーネルへの呼び出しであり、ロケールの影響を受けません。ロケールは純粋にユーザーレベルで存在します。
  • @goldilocks 'は" UNIXシステムの基本の100%は、C "でコーディングされています。あるレベルでは、少しのアセンブラ、またはおそらくアセンブリのようなCが必要です。例としては、ブートローダーローダー(タイプミスなし)、タスク切り替えの実際のプロセス、および他のいくつかの同様に低レベルの機能。それに加えて、C(または高級言語)がコードベース全体で使用される可能性が高いことに同意します。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です