Warum wird wchar_t im Code für Linux / verwandte Plattformen nicht häufig verwendet?

Lesezeit: 6 Minuten

Das fasziniert mich, also werde ich fragen – aus welchem ​​Grund wchar_t wird auf Linux/Linux-ähnlichen Systemen nicht so häufig verwendet wie auf Windows? Insbesondere verwendet die Windows-API wchar_t intern, während ich glaube, dass Linux dies nicht tut, und dies spiegelt sich in einer Reihe von Open-Source-Paketen wider, die verwendet werden char Typen.

Mein Verständnis ist, dass ein Charakter gegeben ist c was mehrere Bytes benötigt, um es darzustellen, dann in a char[] bilden c ist auf mehrere Teile aufgeteilt char* während es eine einzelne Einheit in bildet wchar_t[]. Ist es dann nicht einfacher zu bedienen wchar_t stets? Habe ich einen technischen Grund übersehen, der diesen Unterschied negiert? Oder ist es nur ein Adoptionsproblem?

wchar_t ist ein breites Zeichen mit plattformdefinierter Breite, was nicht wirklich viel hilft.

UTF-8-Zeichen umfassen 1–4 Bytes pro Zeichen. UCS-2, das genau 2 Bytes pro Zeichen umfasst, ist jetzt veraltet und kann nicht den vollständigen Unicode-Zeichensatz darstellen.

Linux-Anwendungen, die Unicode unterstützen, tun dies in der Regel richtig, oberhalb der byteweisen Speicherschicht. Windows-Anwendungen neigen zu dieser dummen Annahme, dass nur zwei Bytes ausreichen.

wchar_tWikipedia-Artikel geht kurz darauf ein.

  • Windows verwendet UTF-16, was nicht davon ausgeht, dass zwei Bytes ausreichen. UTF-16 kann die Gesamtheit von Unicode darstellen. Wikipedia-Artikel von UTF-16 kurz darauf eingehen 🙂

    – Joey

    3. Januar 2011 um 21:06 Uhr


  • Auf der anderen Seite gehen viele Linux-Apps von der “dummen Annahme” aus, dass UTF-8 bedeutet, dass sie nichts ändern müssen, damit ihr Code gemäß dem Unicode-Standard korrekt funktioniert, und weiterhin Plain verwenden können char *s überall und achten Sie nicht auf die Dinge.

    – Billy ONeal

    3. Januar 2011 um 21:07 Uhr

  • @Joey: Ja, und genau deshalb ist Windows UTF-16 am Ende nicht besser als UTF-8: Sie können die Zeichengröße nicht vorhersagen. Von nun an können Sie sich innerhalb von Zeichenfolgen nicht um eine bestimmte Anzahl von Zeichen bewegen. Was bringt es also, beim Schreiben englischer Nachrichten doppelt so viel Platz zu verwenden?

    – kriss

    3. Januar 2011 um 21:12 Uhr

  • @kriss @Tomalak @Joey: Denken Sie daran, dass beim Hinzufügen von “Unicode” zu Win32 2 Bytes ausreichten, um jeden Codepunkt zu codieren. (NT3.51 wurde lange vor 1996 ausgeliefert, als UTF-16 eingeführt wurde) Aus diesem Grund verwendet Windows jetzt UTF-16 – sie hatten sich bereits für die Verwendung von wchar_t entschieden und konnten die gesamte API nicht beschädigen. Auch wenn Ihre App nur UCS-2 verwendet, können Sie die meisten modernen Sprachen problemlos codieren.

    – Billy ONeal

    3. Januar 2011 um 21:20 Uhr

  • @kriss: Vermächtnis. Windows hat von Anfang an UCS-2 verwendet und der Wechsel zu UTF-16 ist das Sinnvollste. Java hat in dieser Hinsicht ein ähnliches Erbe. Damals UCS-2 könnte stellen den gesamten Unicode dar, wobei Codeeinheiten und Codepunkte äquivalent sind – was an sich eine sehr schöne Sache ist, unabhängig von den Speicheranforderungen für Text (und Unicode-Text ist sehr wahrscheinlich nicht der größte Teil, der Ihren Festplattenspeicher verbraucht). Also keine wirkliche Überraschung warum diese Designwahl wurde getroffen. (weiter lesen)

    – Joey

    3. Januar 2011 um 21:20 Uhr


Die ersten Leute, die UTF-8 auf einer Unix-basierten Plattform verwendeten erklärt:

Der Unicode-Standard [then at version 1.1]
definiert einen angemessenen Zeichensatz, aber eine unvernünftige Darstellung [UCS-2]. Es besagt, dass alle Zeichen 16 Bit breit sind [no longer true]
und werden in 16-Bit-Einheiten kommuniziert und gespeichert. Es reserviert auch ein Zeichenpaar (hexadezimal FFFE und FEFF), um die Byte-Reihenfolge im übertragenen Text zu erkennen, was den Zustand im Bytestrom erfordert. (Das Unicode-Konsortium dachte an Dateien, nicht an Pipes.) Um diese Kodierung zu übernehmen, hätten wir den gesamten Text, der in Plan 9 ein- und ausgeht, zwischen ASCII und Unicode konvertieren müssen, was nicht möglich ist. Innerhalb eines einzigen Programms, das alle Ein- und Ausgaben beherrscht, ist es möglich, Zeichen als 16-Bit-Mengen zu definieren; im Kontext eines vernetzten Systems mit Hunderten von Anwendungen auf diversen Maschinen unterschiedlicher Hersteller [italics mine]es ist unmöglich.

Der kursiv gedruckte Teil ist weniger relevant für Windows-Systeme, die eine Vorliebe für monolithische Anwendungen (Microsoft Office), nicht-diverse Maschinen (alles ist ein x86 und damit Little-Endian) und einen einzelnen Betriebssystemanbieter haben.

Und die Unix-Philosophie, kleine Einzweckprogramme zu haben, bedeutet, dass weniger von ihnen ernsthafte Zeichenmanipulationen vornehmen müssen.

Der Quellcode für unsere Tools und Anwendungen war bereits für die Arbeit mit Latin-1 konvertiert, also ‘8-Bit-sicher’, aber die Konvertierung in den Unicode-Standard und UTF[-8] ist mehr beteiligt. Einige Programme mussten überhaupt nicht geändert werden: catzum Beispiel, interpretiert seine Argumentzeichenfolgen, die in UTF geliefert werden[-8]als Dateinamen, die es uninterpretiert an die übergibt
open Systemaufruf und kopiert dann einfach Bytes von seinem Eingang zu seinem Ausgang; es trifft niemals Entscheidungen basierend auf den Werten der Bytes … Die meisten Programme benötigten jedoch bescheidene Änderungen.

… Nur wenige Werkzeuge müssen tatsächlich mit Runen arbeiten [Unicode code points]
im Inneren; Typischerweise müssen sie nur nach dem letzten Schrägstrich in einem Dateinamen und ähnlichen trivialen Aufgaben suchen. Von den 170 C-Quellprogrammen … enthalten nur noch 23 das Wort Rune.

Die Programme, die Runen intern speichern, sind meistens solche, deren Daseinsberechtigung die Zeichenmanipulation ist: sam (der Texteditor),
sed, sort, tr, troff, (das Fenstersystem und der Terminalemulator) und so weiter. Um zu entscheiden, ob mit Runen oder UTF-codierten Byte-Strings gerechnet werden soll, müssen die Kosten für die Konvertierung der Daten beim Lesen und Schreiben gegen die Kosten für die Konvertierung des relevanten Texts bei Bedarf abgewogen werden. Für Programme wie Editoren, die lange mit einem relativ konstanten Datenbestand laufen, sind Runen die bessere Wahl…

UTF-32 mit direkt zugänglichen Codepunkten ist in der Tat praktischer, wenn Sie Zeicheneigenschaften wie Kategorien und Fallzuordnungen benötigen.

Aber Widechars sind unter Linux aus dem gleichen Grund umständlich zu verwenden, aus dem UTF-8 unter Windows umständlich zu verwenden ist. GNU libc hat keine _wfopen oder _wstat Funktion.

UTF-8, das zu ASCII kompatibel ist, ermöglicht es, Unicode etwas zu ignorieren.

Oft ist es Programmen egal (und müssen sich auch nicht darum kümmern), was die Eingabe ist, solange es kein \0 gibt, das Strings beenden könnte. Sehen:

char buf[whatever];
printf("Your favorite pizza topping is which?\n");
fgets(buf, sizeof(buf), stdin); /* Jalapeños */
printf("%s it shall be.\n", buf);

Die einzigen Fälle, in denen ich merkte, dass ich Unicode-Unterstützung benötigte, waren, wenn ich ein Multibyte-Zeichen als einzelne Einheit (wchar_t) haben musste; zB wenn die Anzahl der Zeichen in einer Zeichenfolge gezählt werden muss, anstatt Bytes. iconv von utf-8 bis wchar_t erledigt das schnell. Für größere Probleme wie Leerzeichen ohne Breite und das Kombinieren diakritischer Zeichen wird etwas Schwerwiegenderes wie icu benötigt – aber wie oft macht man das überhaupt?

  • Häufiger ist der Vergleich ohne Berücksichtigung der Groß-/Kleinschreibung. Aber Linux braucht es nicht für Dateinamen.

    – dan04

    4. Januar 2011 um 1:41 Uhr

  • @dan04: Und ein Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung ist sowieso problematisch, da es richtig gemacht wird, abhängig vom Gebietsschema / der Kultur zu sein (z. B. ein Großbuchstaben i auf Türkisch ist nicht ein I) … weshalb die einzig vernünftige Option darin besteht, die Groß- und Kleinschreibung zu beachten, IMO.

    – Tim Čas

    4. September 2016 um 20:11 Uhr


Benutzer-Avatar
Villintehaspam

wchar_t ist nicht auf allen Plattformen gleich groß. Unter Windows ist es eine UTF-16-Codeeinheit, die zwei Bytes verwendet. Auf anderen Plattformen werden normalerweise 4 Bytes verwendet (für UCS-4/UTF-32). Es ist daher unwahrscheinlich, dass sich diese Plattformen bei der Verwendung standardisieren würden wchar_tda es viel Platz verschwenden würde.

1075430cookie-checkWarum wird wchar_t im Code für Linux / verwandte Plattformen nicht häufig verwendet?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy