Je vais demander quelle est probablement une question assez controversée: "Un des encodages les plus populaires, UTF-16, devrait-il être considéré comme dangereux?"
Pourquoi je pose cette question?
Combien de programmeurs sont conscients du fait qu'UTF-16 est en réalité un encodage à longueur variable? J'entends par là qu'il existe des points de code qui, représentés par des paires de substitution, prennent plus d'un élément.
Je connais; De nombreuses applications, infrastructures et API utilisent UTF-16, telles que la chaîne Java, la chaîne C #, les API Win32, les bibliothèques d'interface graphique Qt, la bibliothèque ICU Unicode, etc. Cependant, le traitement comporte de nombreux bogues de caractères hors BMP (caractères qui devraient être codés en utilisant deux éléments UTF-16).
Par exemple, essayez d’éditer l’un de ces caractères:
- 𝄞 ( U + 1D11E ) SYMBOLE MUSICAL G CLEF
- 𝕥 ( U + 1D565 ) MINUSCULE MATHÉMATIQUE AJOURÉE T
- 𝟶 ( U + 1D7F6 ) CHIFFRE MATHÉMATIQUE À MONOSPACE ZÉRO
- 𠂊 ( U + 2008A ) Caractère Han
Il se peut que vous en manquiez, en fonction des polices que vous avez installées. Ces caractères sont tous en dehors du plan BMP (Basic Multilingual Plane). Si vous ne pouvez pas voir ces caractères, vous pouvez également essayer de les regarder dans la référence de caractère Unicode .
Par exemple, essayez de créer des noms de fichiers sous Windows contenant ces caractères. essayez de supprimer ces caractères avec un "retour arrière" pour voir comment ils se comportent dans différentes applications qui utilisent UTF-16. J'ai fait des tests et les résultats sont assez mauvais:
- Opera a des problèmes pour les éditer (effacez les 2 appuis nécessaires sur le retour arrière)
- Le Bloc-notes ne peut pas les traiter correctement (supprimez les 2 appuis requis sur le retour arrière).
- La modification des noms de fichier dans les boîtes de dialogue de la fenêtre est interrompue (supprimer 2 appuis requis sur le retour arrière)
- Toutes les applications QT3 ne peuvent pas les gérer - affichez deux carrés vides au lieu d'un symbole.
- Python n'encode pas correctement ces caractères lorsqu'il est utilisé directement
u'X'!=unicode('X','utf-16')
sur certaines plates-formes lorsque X est un caractère extérieur à BMP. - Python 2.5 unicodedata ne parvient pas à obtenir les propriétés de tels caractères lorsque python est compilé avec des chaînes Unicode UTF-16.
- StackOverflow semble supprimer ces caractères du texte s’il est directement modifié en tant que caractères Unicode (ces caractères sont affichés à l’aide d’échappements HTML Unicode).
- WinForms TextBox peut générer une chaîne non valide lorsqu'il est limité avec MaxLength.
Il semble que ces bogues soient extrêmement faciles à trouver dans de nombreuses applications utilisant UTF-16.
Alors ... Pensez-vous que l'UTF-16 devrait être considéré comme dangereux?
Réponses:
Opinion: Oui, UTF-16 devrait être considéré comme nuisible . La raison même de son existence est qu’il ya quelque temps, on pensait à tort que widechar allait devenir ce que l’UCS-4 est maintenant.
Malgré "l'anglo-centrisme" d'UTF-8, il convient de le considérer comme le seul encodage utile pour le texte. On peut faire valoir que les codes sources des programmes, les pages Web et les fichiers XML, les noms de fichiers du système d'exploitation et les autres interfaces de texte d'ordinateur à ordinateur n'auraient jamais existé. Mais quand ils le font, le texte n'est pas seulement pour les lecteurs humains.
D'autre part, les frais généraux UTF-8 sont un faible prix à payer alors qu'ils présentent des avantages importants. Des avantages tels que la compatibilité avec du code non au courant qui passe simplement des chaînes avec
char*
. C'est une bonne chose. Il y a peu de caractères utiles qui sont plus courts dans UTF-16 que dans UTF-8.Je crois que tous les autres encodages vont finir par mourir. Cela implique que MS-Windows, Java, ICU et Python cessent de l'utiliser comme leur favori. Après de longues recherches et discussions, les conventions de développement de mon entreprise interdisent l’utilisation de UTF-16 partout, à l’exception des appels API de système d’exploitation, et ce, malgré l’importance des performances de nos applications et le fait que nous utilisons Windows. Les fonctions de conversion ont été développées pour convertir les UTF8 toujours supposés
std::string
en UTF-16 natif, que Windows ne prend pas correctement en charge .Aux personnes qui disent " utilisez ce qui est nécessaire où cela est nécessaire ", je dis: il est extrêmement avantageux d'utiliser le même encodage partout, et je ne vois aucune raison suffisante pour faire autrement. En particulier, je pense que l'ajout
wchar_t
au C ++ était une erreur, de même que les ajouts Unicode à C ++ 0x. Ce qui doit cependant être exigé des implémentations STL, c’est que chaque paramètrestd::string
ouchar*
paramètre serait considéré comme compatible avec unicode.Je suis également contre l’ approche « utilise ce que tu veux ». Je ne vois aucune raison pour une telle liberté. Il y a suffisamment de confusion au sujet du texte, ce qui entraîne tout ce logiciel cassé. Cela dit, je suis convaincu que les programmeurs doivent enfin parvenir à un consensus sur le format UTF-8. (Je viens d'un pays qui ne parle pas l'asci et j'ai grandi sous Windows. On m'attend donc à ce que je m'attaque pour la dernière fois à UTF-16 pour des raisons religieuses).
J'aimerais partager davantage d'informations sur la manière dont je rédige du texte sous Windows et sur ce que je recommande à tout le monde pour l'exactitude vérifiée au moment de la compilation, la facilité d'utilisation et une meilleure multiplicité du code. La suggestion diffère substantiellement de ce qui est généralement recommandé comme la bonne façon d'utiliser Unicode sur Windows. Pourtant, une recherche approfondie de ces recommandations a abouti à la même conclusion. Alors, voici:
wchar_t
oustd::wstring
dans aucun endroit autre que le point adjacent aux API acceptant UTF-16._T("")
ouL""
UTF-16 littéraux (OMI Ceux - ci devraient être retirés de la norme, comme une partie de deprecation UTF-16)._UNICODE
constante, tels queLPTSTR
ouCreateWindow()
._UNICODE
toujours défini, pour éviter de passer deschar*
chaînes à WinAPI compilées en silencestd::strings
etchar*
n'importe où dans le programme sont considérés comme UTF-8 (sauf indication contraire)std::string
, bien que vous puissiez passer char * ou chaîne littérale àconvert(const std::string &)
.utilisez uniquement les fonctions Win32 qui acceptent widechars (
LPWSTR
). Jamais ceux qui acceptentLPTSTR
ouLPSTR
. Passer les paramètres de cette façon:(La stratégie utilise les fonctions de conversion ci-dessous.)
Avec les chaînes MFC:
Utilisation de fichiers, noms de fichiers et fstream sous Windows:
std::string
ou d'const char*
argument de nom de fichier à lafstream
famille. MSVC STL ne prend pas en charge les arguments UTF-8, mais possède une extension non standard qui doit être utilisée comme suit:Convertir les
std::string
arguments enstd::wstring
avecUtils::Convert
:Nous devrons supprimer manuellement le convertisseur, lorsque l'attitude de MSVC vis-à-vis des
fstream
changements.fstream
cas de recherche / discussion 4215 unicode pour plus d'informations.fopen()
pour des raisons RAII / OOD. Si nécessaire, utilisez_wfopen()
et les conventions WinAPI ci-dessus.la source
Les points de code Unicode ne sont pas des caractères! Parfois, ils ne sont même pas des glyphes (formes visuelles).
Quelques exemples:
La seule façon d'obtenir une édition Unicode correcte consiste à utiliser une bibliothèque écrite par un expert ou à devenir un expert et à en écrire une vous-même. Si vous ne faites que compter les points de code, vous vivez dans un état de péché.
la source
Il existe une règle simple sur le formulaire de transformation Unicode (UTF) à utiliser: - utf-8 pour le stockage et la communication - utf-16 pour le traitement des données - vous pouvez utiliser utf-32 si la plupart des API de plate-forme que vous utilisez sont utf-32 (commun dans le monde UNIX).
La plupart des systèmes actuels utilisent utf-16 (Windows, Mac OS, Java, .NET, ICU, Qt). Voir aussi ce document: http://unicode.org/notes/tn12/
Retour à "UTF-16 en tant que nocif", je dirais: certainement pas.
Les personnes qui ont peur des substituts (pensant transformer Unicode en un codage de longueur variable) ne comprennent pas les complexités de l’autre (bien plus grandes) qui rendent très complexe le mappage entre les caractères et un point de code Unicode: combinaison de caractères, ligatures, sélecteurs de variation , caractères de contrôle, etc.
Il suffit de lire cette série ici http://www.siao2.com/2009/06/29/9800913.aspx et de voir comment le format UTF-16 devient un problème facile.
la source
equalsIgnoreCase
méthode de la classe Java Core String (ainsi que d’autres dans la classe String) qui n’aurait jamais existé si Java avait utilisé UTF-8 ou UTF-32. Il y a des millions de ces bombes endormies dans n'importe quel code qui utilise le format UTF-16, et j'en ai marre. UTF-16 est une variole vicieuse qui envahit notre logiciel de bogues insidieux pour toujours. Il est clairement nocif et devrait être déconseillé et interdit..Substring(1)
dans .NET est un exemple trivial de quelque chose qui rompt la prise en charge de tous les Unicode non BMP. Tout ce qui utilise UTF-16 a ce problème; il est trop facile de le traiter comme un codage à largeur fixe et vous voyez trop rarement des problèmes. Cela en fait un encodage nuisible si vous souhaitez prendre en charge Unicode.Oui absolument.
Pourquoi? Cela a à voir avec l' exercice du code .
Si vous examinez les statistiques d'utilisation des points de code d'un grand corpus de Tom Christiansen, vous constaterez que les points de code BMP trans-8 bits sont utilisés avec plusieurs ordres si leur ampleur est supérieure à celle des points de code non-BMP:
Prenez le dicton TDD: "Le code non testé est un code cassé" et reformulez-le ainsi: "le code non exercé est un code cassé" et pensez à la fréquence à laquelle les programmeurs doivent traiter des points de code non BMP.
Les bogues liés au fait de ne pas traiter l'UTF-16 en tant qu'encodage à largeur variable sont beaucoup plus susceptibles de passer inaperçus que les bogues équivalents dans UTF-8 . Certains langages de programmation ne garantissent toujours pas l’utilisation de UTF-16 à la place de UCS-2, et certains langages de programmation de haut niveau offrent un accès aux unités de code au lieu de points de code (même le C est censé vous donner accès à codepoints si vous utilisez
wchar_t
, indépendamment de ce que certaines plates-formes peuvent faire).la source
Je suggérerais que penser que UTF-16 puisse être considéré comme préjudiciable signifie que vous devez acquérir une meilleure compréhension de Unicode .
Depuis que j'ai été critiqué pour avoir présenté mon opinion sur une question subjective, laissez-moi élaborer. Qu'est-ce qui vous gêne au sujet de l'UTF-16? Préféreriez-vous que tout soit encodé en UTF-8? UTF-7? Ou que diriez-vous de UCS-4? Bien sûr, certaines applications ne sont pas conçues pour gérer tout code à caractère unique, mais elles sont nécessaires, en particulier dans le domaine de l'information global, pour la communication entre frontières internationales.
Mais vraiment, si vous pensez que UTF-16 devrait être considéré comme nuisible parce que cela crée de la confusion ou peut être mal appliqué (unicode peut certainement l'être), alors quelle méthode de codage de caractère serait considérée comme non nuisible?
EDIT: Pour clarifier: Pourquoi une implémentation incorrecte d’une norme est-elle le reflet de la qualité de la norme elle-même? Comme d'autres l'ont noté par la suite, le simple fait qu'une application utilise un outil de manière inappropriée ne signifie pas que l'outil lui-même est défectueux. Si tel était le cas, nous pourrions probablement dire des choses comme "mot clé var considéré comme nuisible" ou "threading considéré comme nuisible". Je pense que la question confond la qualité et la nature de la norme avec les difficultés rencontrées par de nombreux programmeurs pour la mettre en œuvre et l’utiliser correctement, ce qui, selon moi, découle davantage de leur manque de compréhension du fonctionnement de l’unicode, plutôt que de l’unicode lui-même.
la source
Il n'y a rien de mal avec le codage Utf-16. Mais les langues qui traitent les unités 16 bits comme des caractères devraient probablement être considérées comme mal conçues. Avoir un type nommé '
char
' qui ne représente pas toujours un caractère est assez déroutant. Étant donné que la plupart des développeurs s'attendent à ce qu'un type de caractère représente un point de code ou un caractère, une grande partie du code sera probablement endommagé s'il est exposé à des caractères supérieurs à BMP.Notez cependant que même en utilisant utf-32 ne signifie pas que chaque point de code 32 bits représentera toujours un caractère. En raison de la combinaison de caractères, un caractère réel peut être constitué de plusieurs points de code. Unicode n'est jamais trivial.
BTW. Il existe probablement la même classe de bogues avec les plates-formes et les applications qui s’attendent à ce que les caractères soient de 8 bits, alimentés par Utf-8.
la source
CodePoint
type contenant un seul point de code (21 bits), unCodeUnit
type contenant une seule unité de code (16 bits pour UTF-16) et unCharacter
type devrait idéalement prendre en charge un graphème complet. Mais cela le rend fonctionnellement équivalent à unString
...Mon choix personnel est de toujours utiliser le format UTF-8. C'est la norme sous Linux pour presque tout. Il est rétrocompatible avec de nombreuses applications existantes. Il existe une surcharge très minime en termes d'espace supplémentaire utilisé pour les caractères non latins par rapport aux autres formats UTF, et une économie d'espace importante pour les caractères latins. Sur le Web, les langues latines règnent en maître et je pense qu’elles le feront dans un avenir prévisible. Et pour répondre à l’un des arguments principaux de la publication originale: presque tous les programmeurs savent qu’UTF-8 comportera parfois des caractères multi-octets. Tout le monde ne traite pas cela correctement, mais ils sont généralement au courant, ce qui est plus que ce qui peut être dit pour UTF-16. Mais, bien sûr, vous devez choisir celui qui convient le mieux à votre application. C'est pourquoi il y en a plus d'un en premier lieu.
la source
Eh bien, il existe un encodage qui utilise des symboles de taille fixe. Je veux certainement dire UTF-32. Mais 4 octets pour chaque symbole, c'est trop d'espace perdu, pourquoi l'utiliserions-nous dans des situations de tous les jours?
Selon moi, la plupart des problèmes découlent du fait que certains logiciels ont pris du retard par rapport à la norme Unicode, mais qu’ils n’ont pas été rapides à corriger la situation. Opera, Windows, Python, Qt - ils sont tous apparus avant que UTF-16 ne soit largement connu ou même né. Je peux toutefois confirmer que dans Opera, Windows Explorer et le Bloc-notes, les problèmes avec les caractères extérieurs à BMP ne sont plus d'actualité (du moins sur mon PC). Quoi qu'il en soit, si les programmes ne reconnaissent pas les paires de substitution, ils n'utilisent pas UTF-16. Quels que soient les problèmes rencontrés lors de l'utilisation de tels programmes, ils n'ont rien à voir avec le format UTF-16.
Cependant, je pense que les problèmes des logiciels existants avec uniquement le support BMP sont quelque peu exagérés. Les caractères hors BMP ne se rencontrent que dans des cas et des zones très spécifiques. Selon la FAQ officielle Unicode , "même dans les textes en Asie de l’Est, l’incidence des paires de substitution devrait représenter bien moins de 1% de l’ensemble du stockage de texte en moyenne". Bien entendu, les caractères extérieurs à BMP ne doivent pas être négligés car un programme n'est pas conforme à Unicode, mais la plupart des programmes ne sont pas conçus pour travailler avec des textes contenant de tels caractères. C'est pourquoi s'ils ne l'appuient pas, c'est désagréable, mais pas une catastrophe.
Considérons maintenant l'alternative. Si UTF-16 n'existait pas, le codage ne conviendrait pas pour les textes non-ASCII et tous les logiciels créés pour UCS-2 devraient être entièrement repensés pour rester compatibles avec Unicode. Ce dernier ne ralentirait probablement que l’adoption de l’Unicode. De plus, nous n'aurions pas pu maintenir la compatibilité avec le texte dans UCS-2 comme le fait UTF-8 en ce qui concerne ASCII.
Maintenant, en mettant de côté toutes les questions héritées, quels sont les arguments contre le codage lui-même? Je doute vraiment que les développeurs de nos jours ne sachent pas que UTF-16 a une longueur variable, il est écrit partout en commençant par Wikipedia. UTF-16 est beaucoup moins difficile à analyser que UTF-8, si quelqu'un a signalé la complexité comme un problème possible. De plus, il est faux de penser qu'il est facile de gâcher la détermination de la longueur de chaîne uniquement en UTF-16. Si vous utilisez UTF-8 ou UTF-32, vous devez toujours savoir qu'un point de code Unicode ne signifie pas nécessairement un caractère. En dehors de cela, je ne pense pas qu'il y ait quelque chose de substantiel contre le codage.
Par conséquent, je ne pense pas que le codage lui-même devrait être considéré comme nuisible. UTF-16 est un compromis entre simplicité et compacité. Il n'y a pas de mal à utiliser ce qui est nécessaire là où il le faut . Dans certains cas, vous devez rester compatible avec ASCII et UTF-8, dans certains cas, vous souhaitez travailler avec les idéogrammes han et conserver de l'espace en utilisant UTF-16, dans certains cas, vous avez besoin de représentations universelles de caractères. encodage de longueur. Utilisez ce qui est plus approprié, faites-le correctement.
la source
Des années d’internationalisation du travail de Windows, en particulier dans les langues d’Asie orientale, m’auraient peut-être corrompu, mais je me tourne davantage vers UTF-16 pour les représentations de chaînes internes au programme et UTF-8 pour le stockage en réseau ou sur fichier de documents de type texte en clair. UTF-16 peut généralement être traité plus rapidement sous Windows, c’est donc le principal avantage de l’utilisation de UTF-16 sous Windows.
Le passage à la norme UTF-16 a considérablement amélioré l’adéquation des produits moyens traités avec du texte international. Il n'y a que quelques cas étroits dans lesquels les paires de substitution doivent être prises en compte (suppressions, insertions et sauts de ligne, en gros) et le cas moyen est généralement direct. Et contrairement aux encodages antérieurs tels que les variantes JIS, UTF-16 limite les paires de substitution à une plage très étroite, de sorte que la vérification est très rapide et fonctionne dans les deux sens.
Certes, il est aussi rapide en UTF-8 correctement codé. Mais il existe également de nombreuses applications UTF-8 cassées qui codent de manière incorrecte des paires de substitution sous forme de deux séquences UTF-8. Donc, UTF-8 ne garantit pas le salut non plus.
IE gère assez bien les paires de substitution depuis 2000 environ, même s'il les convertit généralement des pages UTF-8 en une représentation interne UTF-16; Je suis à peu près sûr que Firefox a bien compris, donc je me fiche de ce que fait Opera.
UTF-32 (alias UCS4) est inutile pour la plupart des applications car il nécessite peu d’espace et qu’il s’agit donc d’un nonstarter.
la source
UTF-8 est définitivement le chemin à parcourir, éventuellement accompagné de UTF-32 pour une utilisation interne dans les algorithmes nécessitant un accès aléatoire hautes performances (mais qui ignore la combinaison de caractères).
UTF-16 et UTF-32 (ainsi que leurs variantes LE / BE) souffrent de problèmes de réseau, ils ne doivent donc jamais être utilisés à l'extérieur.
la source
UTF-16? définitivement nuisible. Juste mon grain de sel ici, mais il y a exactement trois encodages acceptables pour du texte dans un programme:
nombres de codes entiers ("CP"?): un tableau des entiers les plus grands qui conviennent à votre langage de programmation et à votre plate-forme (décomposition en ASCII dans la limite des faibles ressources). Doit être int32 sur les ordinateurs plus anciens et int64 sur tout ce qui a un adressage 64 bits.
De toute évidence, les interfaces avec le code existant utilisent le codage nécessaire pour que l'ancien code fonctionne correctement.
la source
U+10ffff
max sortira de la fenêtre quand (pas si) ils manqueront de points de code. Cela dit, utiliser int32 sur un système p64 pour la vitesse est probablement sans danger, car je doute qu'ils dépasserontU+ffffffff
avant que vous ne soyez obligé de réécrire votre code pour les systèmes 128 bits vers 2050. (C'est le point de "utiliser le plus grand int est pratique "par opposition à" le plus grand disponible "(qui serait probablement int256 ou bignums ou quelque chose).)U+10FFFF
. C'est vraiment l' une de ces situations où 21 bits est suffisant pour tout le monde.Unicode définit des points de code allant jusqu'à 0x10FFFF (1 114 112 codes), toutes les applications fonctionnant dans un environnement multilingue traitant des chaînes / noms de fichiers, etc. doivent le gérer correctement.
Utf-16 : ne couvre que 1 112 064 codes. Bien que ceux situés à la fin de l’ Unicode proviennent des plans 15 à 16 (Zone d’utilisation privée). Il ne peut plus se développer dans le futur si ce n’est briser le concept Utf-16 .
Utf-8 : couvre théoriquement 2 216 757 376 codes. La plage actuelle de codes Unicode peut être représentée par une séquence maximale de 4 octets. Il ne souffre pas du problème d' ordre d'octet , il est "compatible" avec ascii.
Utf-32 : couvre théoriquement 2 ^ 32 = 4 294 967 296 codes. Actuellement, il n'est pas codé en longueur variable et ne le sera probablement pas à l'avenir.
Ces faits sont explicites. Je ne comprends pas préconiser l’usage général de Utf-16 . Il est codé en longueur variable (il n’est pas accessible par index), il a des problèmes pour couvrir toute la plage Unicode , même à l’heure actuelle, l’ordre des octets doit être géré, etc. Je ne vois aucun avantage, sauf qu’il est utilisé nativement dans Windows d'autres lieux. Même si, lors de l’écriture de code multiplate-forme, il est probablement préférable d’utiliser Utf-8 de manière native et d’effectuer des conversions uniquement aux points de terminaison de la manière dépendante de la plate-forme (comme cela a déjà été suggéré). Si l'accès direct par index est nécessaire et que la mémoire n'est pas un problème, vous devez utiliser Utf-32 .
Le principal problème est que de nombreux programmeurs utilisant Windows Unicode = Utf-16 ne savent même pas ou ignorent qu'il s'agit d'un codage à longueur variable.
La manière dont il est généralement utilisé dans la plate-forme * nix est plutôt bonne: chaînes c (char *) interprétées comme codées en Utf-8 , chaînes c larges (wchar_t *) interprétées en tant que Utf-32 .
la source
Ajoutez ceci à la liste:
Source: Michael S. Kaplan Blog MSDN
la source
Je ne dirais pas nécessairement que l'UTF-16 est nocif. Ce n'est pas élégant, mais il sert à la compatibilité ascendante avec UCS-2, tout comme le GB18030 avec GB2312 et l'UTF-8 avec ASCII.
Cependant, apporter un changement fondamental à la structure d'Unicode en cours de route, après que Microsoft et Sun aient mis au point d'énormes APIs autour de caractères 16 bits, était préjudiciable. L'échec de la sensibilisation au changement était plus préjudiciable.
la source
UTF-16 est le meilleur compromis entre traitement et espace . C'est pourquoi la plupart des grandes plates-formes (Win32, Java, .NET) l'utilisent pour la représentation interne des chaînes.
la source
Je n'ai jamais compris l'intérêt de l'UTF-16. Si vous voulez la représentation la moins encombrante, utilisez UTF-8. Si vous voulez pouvoir traiter le texte comme une longueur fixe, utilisez UTF-32. Si vous ne voulez ni l'un ni l'autre, utilisez UTF-16. Pire encore, puisque tous les caractères communs (plan multilingue de base) dans UTF-16 tiennent dans un seul point de code, les bogues qui supposent que UTF-16 est de longueur fixe seront subtils et difficiles à trouver, alors que si vous essayez de le faire Avec UTF-8, votre code échouera rapidement et fort dès que vous tenterez d’internationaliser.
la source
Comme je ne peux pas encore commenter, je publie cette réponse en tant que réponse, car il semble que je ne peux pas autrement contacter les auteurs de
utf8everywhere.org
. Dommage que je n’obtienne pas automatiquement le privilège de commentaire, car j’ai assez de réputation sur d’autres échanges de pile.Ceci est considéré comme un commentaire à l' opinion: Oui, UTF-16 devrait être considéré comme une réponse nuisible .
Une petite correction:
Pour éviter de faire passer accidentellement un fichier UTF-8
char*
dans les versions ANSI-string des fonctions Windows-API, il convient de définirUNICODE
, non_UNICODE
._UNICODE
fonctions de cartes comme_tcslen
àwcslen
, nonMessageBox
àMessageBoxW
. Au lieu de cela, laUNICODE
définition prend soin de ce dernier. Pour preuve, cela provient de l'en-WinUser.h
tête de MS Visual Studio 2005 :Au minimum, cette erreur devrait être corrigée
utf8everywhere.org
.Une suggestion:
Peut-être que le guide devrait contenir un exemple d'utilisation explicite de la version Wide-string d'une structure de données, pour le rendre moins facile à manquer / oublier. L'utilisation de versions de chaînes de données Wide-string en plus de l'utilisation de versions de fonctions Wide-string réduit encore les risques d'appeler accidentellement une version ANSI d'une telle fonction.
Exemple de l'exemple:
la source
_UNICODE
est toujours là :(Quelqu'un a dit que UCS4 et UTF-32 étaient les mêmes. Non, mais je sais ce que tu veux dire. L'un d'eux est un encodage de l'autre, cependant. J'aurais aimé qu'ils spécifient l'idée de spécifier l'endianité dès le départ pour ne pas avoir la bataille des endianesses ici aussi. N'avaient-ils pas vu cela venir? Au moins, UTF-8 est identique partout (à moins que quelqu'un ne respecte la spécification d'origine avec 6 octets).
Si vous utilisez UTF-16, vous devez inclure la gestion des caractères multi-octets. Vous ne pouvez pas aller au Nième caractère en indexant 2N dans un tableau d'octets. Vous devez marcher ou avoir des index de caractère. Sinon, vous avez écrit un bug.
La spécification actuelle de C ++ indique que UTF-32 et UTF-16 peuvent avoir des variantes little-endian, big-endian et non spécifiée. Vraiment? Si Unicode avait spécifié que tout le monde devait faire du little-endian depuis le début, tout aurait été plus simple. (J'aurais bien aimé le big-endian également.) Au lieu de cela, certaines personnes l'ont mis en œuvre d'une manière, d'une autre, et maintenant nous sommes coincés avec de la bêtise pour rien. Parfois, il est embarrassant d'être un ingénieur en logiciel.
la source
Je ne pense pas que ce soit nocif si le développeur est suffisamment prudent.
Et ils devraient accepter ce compromis s’ils le savent aussi.
En tant que développeur de logiciels japonais, je trouve UCS-2 assez volumineux et limiter l’espace simplifie apparemment la logique et réduit la mémoire d’exécution. Il est donc suffisant d’utiliser utf-16 sous la limitation UCS-2.
Il existe un système de fichiers ou une autre application qui suppose que les points de code et les octets sont proportionnels, ce qui permet de garantir que le nombre brut de points de code est ajusté à un stockage de taille fixe.
Par exemple, NTFS et VFAT spécifient UCS-2 comme codage de stockage du nom de fichier.
Si ces exemples veulent vraiment étendre au support UCS-4, je pourrais accepter l'utilisation d'utf-8 pour tout, mais la longueur fixe a de bons points comme:
Dans le futur, lorsque la mémoire / la puissance de traitement ne coûteront pas cher, même dans les périphériques intégrés, nous pourrons accepter le périphérique comme étant un peu lent pour éviter les erreurs de cache, les erreurs de page et l'utilisation de mémoire supplémentaire, mais cela n'arrivera pas dans un avenir proche, je suppose ...
la source
Très probablement, mais les alternatives ne doivent pas nécessairement être considérées comme étant bien meilleures.
La question fondamentale est qu’il existe de nombreux concepts différents concernant: les glyphes, les caractères, les points de code et les séquences d’octets. La correspondance entre chacun de ces éléments n’est pas triviale, même à l’aide d’une bibliothèque de normalisation. (Par exemple, certains caractères dans les langues européennes écrits avec un script basé sur le latin ne sont pas écrits avec un seul code codé Unicode. Et c'est à la fin de la complexité!) Ce que cela signifie est que pour que tout soit correct, il est assez surprenant difficile; il faut s'attendre à des bugs bizarres (et au lieu de simplement s'en plaindre ici, informez-en les responsables du logiciel concerné).
Le seul moyen de considérer l'UTF-16 comme dangereux, par opposition à l'UTF-8, par exemple, consiste à coder différemment les points de code en dehors du BMP (en tant que paire de substituts). Si le code souhaite accéder ou itérer par point de code, cela signifie qu'il doit être conscient de la différence. OTOH, cela signifie qu’un corps substantiel de code existant qui suppose que les "caractères" peuvent toujours être insérés dans une quantité de deux octets - une hypothèse assez courante, voire erronée - peut au moins continuer à fonctionner sans tout reconstruire. En d'autres termes, au moins, vous pouvez voir ces caractères qui ne sont pas gérés correctement!
Je voudrais retourner votre question et dire que tout le foutu shebang d'Unicode devrait être considéré comme nuisible et que tout le monde devrait utiliser un codage en 8 bits, sauf que j'ai vu (au cours des 20 dernières années) où cela mène: horrible confusion sur les divers codages ISO 8859, ainsi que sur l’ensemble des codages utilisés pour Cyrillic et la suite EBCDIC, et… eh bien, Unicode pour tous ses défauts est supérieur à celui. Si seulement ce n'était pas un compromis aussi désagréable entre les malentendus des différents pays.
la source