9
votes

Comment le char [] peut-il représenter une chaîne UTF-8?

en C11, un nouveau littéral à chaîne a été ajouté avec le préfixe U8. Cela renvoie une gamme de caractères avec le texte codé sur UTF-8. Comment est-ce possible? N'est-ce pas un caractère normal signé? Ce qui signifie qu'il a un peu moins d'informations à utiliser en raison de la signalisation? Ma logique représenterait qu'une chaîne de texte UTF-8 devrait être une gamme de caractères non signés.


6 commentaires

UTF-8 représente des caractères utilisant plus de 8 bits (qui me confond toujours que UTF-16 est 16 bits). En outre, un caractère est juste un groupe de bits, alors peut-être être signé ou non seulement si vous réfléchissez à la valeur comme étant un nombre. Si vous y pensez comme étant (une partie de) une représentation d'un symbole UTF-8, si le compilateur pense que la zone de la mémoire représente un nombre signé ou non signé n'a pas d'importance. (Ce n'est pas une réponse, juste comment ma logique interprète cela.)


@Oliver Quelle est la partie qui vous confond? UTF-8 est autant 8 bits que UTF-16 est 16 bits.


@MRLISTER UTF-16 caractères prennent 1 ou 2 octets de mémoire. Les caractères UTF-8 peuvent occuper un nombre de byes de mémoire (généralement de 1 à 6 octets). Donc, à mon avis, "UTF-8" serait un codage similaire à 8 bits. Bien que le vrai UTF-8 serait mieux nommé UTF-48 ou similaire. Ou du moins, je pense que c'est comme ça que ça marche. Je n'ai jamais vraiment compris les codages de caractère de largeur variable lorsque je faisais C quelques années il y a quelques années, et maintenant je travaille dans des langues plus heureuses où ce n'est pas vraiment une préoccupation ...


@Oliver: Non, les caractères UTF-16 prennent 1 ou 2 unités 16 bits, c'est donc 2 ou 4 octets sur une implémentation C typique C. Le N dans UTF-N signifie la taille de l'unité "Code", pas la taille d'un caractère dans les bits. Cela détient pour UTF-7, UTF-8, UTF-16 et UTF-32. Tous ceux que l'UTF-32 utilisent un nombre variable d'unités de code par point de code UNICODE.


@Oliver ce qu'il a dit. Et UTF-8 est max 32 bits, pas 48.


Je pense que c'est une très bonne question, puisque la norme C utilise autrement uniquement non signé Char pour les représentations d'octets d'objets.


4 Réponses :


7
votes

n'est pas un caractère normal signé?

Il est dépendant de la mise en œuvre si char est signé ou non signé .

En outre, le bit de signalisation n'est pas "perdu", il peut toujours être utilisé pour représenter des informations, et Char n'est pas nécessairement de 8 bits (cela pourrait être plus important sur certaines plates-formes). < / p>


2 commentaires

"Cela peut aussi être non signé" ... mais pas en même temps :-)


La norme dit char est toujours 1 octet long. Cependant, la taille d'un octet peut varier. Utilisez char_bit (à partir de limites.h ) pour connaître la taille réelle de 1 octet.



1
votes

Non, un bit de signalisation est un peu néanmoins! Et la spécification UTF-8 elle-même ne dit pas que les caractères doivent être non signés.

PS wat est kookwekker voor 'n naam?


0 commentaires

7
votes

Il y a un problème potentiel ici:

si une implémentation avec char_bit == 8 utilise une représentation de la magnitude de signalisation pour char (donc char est signé), alors lorsque UTF-8 nécessite le motif bit-8 10000000 , c'est un négatif 0. SO si la mise en œuvre ne prend en outre pas de ne pas supporter négatif 0, puis une UP- 8 String peut contenir une valeur invalide (piège) de Char , qui est problématique. Même si cela supporte négatif zéro, le fait que le motif de bits 10000000 se compare égal en tant que modèle au motif de bit 00000000 (le terminateur nul) est susceptible de causer des problèmes lors de l'utilisation des données UTF-8 dans un char [] .

Je pense que cela signifie que pour les implémentations de la signature C11, Char doit être non signé. Normalement, il apparaît à la mise en œuvre si Char est signé ou non signé, mais bien sûr si Char SIGNED Résultats en omettant correctement implémenter les littéraux UTF-8 correctement, la mise en œuvre doit simplement choisir non signé. De côté, cela a été le cas pour les implémentations de complément de non-2 de C ++ tout le long, car c ++ permet char ainsi que sans signé char à utiliser pour accéder aux représentations d'objets . C permet uniquement à non signé Char .

Complément et complément 1S 'en 2, les modèles de bits requis pour les données UTF-8 sont des valeurs valides de signées Char , la mise en œuvre est donc libre de faire char soit Signé ou non signé et être toujours en mesure de représenter les chaînes UTF-8 dans Char [] . C'est parce que tous les modèles de 256 bits sont des valeurs de complément de 2 valides, et UTF-8 se produit de ne pas utiliser l'octet 11111111 (1s 'complément zéro négatif).


6 commentaires

Votre message utilise une mauvaise prémisse, à savoir que les implémentations seraient assez idiotes pour permettre à -0 valeurs de caractères. Ils ne sont jamais.


@MR LISTER: Je ne pense pas que ma réponse rend une supposition du tout sur les implémentations réellement effectuées. Il énumère simplement ce qu'ils sont (non) autorisés à faire et, en particulier, la représentation nouvellement exclue par l'exigence de C11 de soutenir UTF-8. À toutes fins pratiques, chaque mise en œuvre est le complément de 2, mais la norme continue de permettre les alternatives (idiotes).


Je pense que votre message est très perspicace, mais voici où je suis confus: la norme C ++ 11 permet à un sans signé caractère et char à utiliser pour l'aliasing (voir §3.10 / 15) et C11 permet même à tous les types de caractères (voir §6.5 / 7). Pour moi, cela signifie que ces types doivent être capables de lire un octet de la valeur 11111111 (ou n'importe quel autre valeur d'octet). En C ++ 11, cela peut être résolu en faisant une plaine char non signé si le complément de 2 2 n'est pas utilisé. Mais en C11, cela ne peut jamais être résolu si le complément de 2 n'est pas utilisé utilisé, car le plaidoyer doit fonctionner avec tous les types de caractères (§6.5 / 7), c'est-à-dire explicitement ...


déclaré signé de caractère signé. Cela signifie que C11 mérite implicitement le complément de 2 (de sorte qu'il n'y a pas de valeurs de piège) tout en permettant une complément et une magnitude de signature de 1 au § 6.2.6.2 / 2. Je pense que c'est un bogue dans la norme. Qu'est-ce que tu penses? Mon avis est que C ++ et C devraient mandater le complément et l'arrêt de 2 "Nous allons soutenir tout ce qui concerne le coût jusqu'à la fin du temps" désordre qui est sérieusement déroutant pour quelqu'un qui veut écrire un code compatible standard. S'il y a toujours un processeur significatif utilisé là-bas qui n'utilise pas le complément de 2 2, on peut facilement utiliser un ...


... Drapeau du compilateur Sélection d'une norme C ou C ++ plus ancienne qui permet de cela.


@ Johncac2: Je n'ai pas les normes à remettre, mais je pense que si tous les types de caractères sont autorisés à aliaser que ne signifie pas vous devez utiliser le complément de 2. Cela signifie simplement que vous devez prendre en charge le zéro négatif pour les types de caractères, si vous n'utilisez pas le complément de 2 2. Cela évite qu'il y ait des valeurs de piège, bien qu'il y ait des valeurs diapitudes différentes comparant égales. Ce dernier, bien qu'il s'agisse d'une défaillance de la mise en œuvre dans la gestion des données UTF-8 à l'aide de la signature de la signature, comme je décris dans la réponse, n'est pas une défaillance de la mise en œuvre d'aliasing.



1
votes

La signature du caractère n'a pas d'importance; UTF8 peut être traitée avec uniquement des opérations de quart et de masque (qui peut être encombrante pour les types signés, mais pas impossible) mais: UTF8 a besoin au moins 8 bits, donc "affirmation (char_bit> = 8);"

Pour illustrer par point: Les fragments suivants ne contiennent aucune opération arithmétique sur la valeur du personnage, seulement Shift & Mask. xxx


1 commentaires

Notez que la norme garantit char_bit ≥ 8.