2010-12-08 2 views
7

à partir de C++ 2003 2,13Conflits: définition de la chaîne wchar_t en standard C++ et implémentation Windows?

Une grande chaîne littérale est de type « réseau de n const wchar_t » et a une durée de stockage statique, où n est la taille de la chaîne tel que défini ci-dessous

La taille d'un littéral de chaîne large est le nombre total de séquences d'échappement, de noms de caractères universels et d'autres caractères, plus un pour l'extrémité L '\ 0'.

à partir de C++ 0x 2.14.5

Une grande chaîne littérale est de type « réseau de n const wchar_t », où n est la taille de la chaîne tel que défini ci-dessous

Le taille d'un char32_t ou littéral de chaîne large est le nombre total de séquences d'échappement, de noms de caractères universels et d'autres caractères, plus un pour l'U '\ 0' ou L '\ 0' final. La taille d'un littéral de chaîne char16_t est le nombre total de séquences d'échappement, de noms de caractères universels et d'autres caractères, plus un pour chaque caractère nécessitant une paire de substitution, plus un pour l'unité de terminaison '0'.

L'instruction dans C++ 2003 est assez vague. Mais en C++ 0x, lors du comptage de la longueur de la chaîne, le littéral chaîne large wchar_t doit être traité de la même manière que char32_t, et différent de char16_t.

Il y a un poste qui indique clairement la façon dont les fenêtres wchar_t met en œuvre dans https://stackoverflow.com/questions/402283?tab=votes%23tab-top

En bref, wchar_t dans les fenêtres est 16bits et codé en utilisant UTF-16. La déclaration en standard laisse apparemment quelque chose de contradictoire sous Windows.

par exemple,

wchar_t kk[] = L"\U000E0005"; 

Cela dépasse 16 bits et UTF-16, il a besoin de deux 16 bits à coder (une paire de substitution).

Cependant, à partir de la norme, kk est un tableau de 2 wchar_t (1 pour le nom universel \ U000E005, 1 pour \ 0). Mais dans le stockage interne, Windows a besoin de 3 objets wchar_t de 16 bits pour le stocker, de 2 wchar_t pour la paire de substitution et de 1 wchar_t pour le 0. Par conséquent, à partir de la définition de tableau, kk est un tableau de 3 wchar_t.

Il semble contradictoire.

Je pense que la solution la plus simple pour Windows est de "bannir" tout ce qui nécessite une paire de substitution dans wchar_t ("bannir" tout unicode en dehors de BMP).

Y a-t-il quelque chose qui ne va pas dans ma compréhension?

Merci.

Répondre

3

La norme requiert que wchar_t soit assez grand pour contenir n'importe quel caractère dans le jeu de caractères pris en charge.Sur la base de cela, je pense que votre prémisse est correcte - il est faux pour VC++ de représenter le seul caractère \U000E0005 en utilisant deux unités wchar_t.

Les caractères en dehors du BMP sont rarement utilisés, et Windows lui-même utilise le codage UTF-16 en interne, il est donc simplement pratique (même incorrect) que VC++ se comporte de cette manière. Cependant, plutôt que de "bannir" de tels caractères, il est probable que la taille de wchar_t augmentera à l'avenir tandis que char16_t prendra sa place dans l'API Windows.

La réponse que vous avez lié à est quelque peu trompeur ainsi:

Sur Linux, un wchar_t est de 4 octets, alors que sous Windows, il est 2-octets

La taille de wchar_t dépend uniquement sur le compilateur et n'a rien à voir avec le système d'exploitation. Il arrive juste que VC++ utilise 2 octets pour wchar_t, mais encore une fois, cela pourrait très bien changer dans le futur.

+0

merci. je l'ai maintenant. il est parfois difficile de comprendre un nouveau concept, mais une fois que vous l'avez compris, il devient plus simple instantanément. – user534498

+0

Windows utilise techniquement 'WCHAR', pas' wchar_t'. Il a été typedeffed comme «short non signé» dans le passé et pourrait devenir «char16_t» dans le futur. Mais honnêtement, je ne vois pas cela se produire - les littéraux de chaîne casseraient. – MSalters

+0

@MSalters: Pourquoi les littéraux de chaînes se briseraient-ils? C'est ce que les macros 'TEXT (" ... ")' sont là pour - les gens n'ont jamais été supposés utiliser des littéraux "L" ... "' crus. Aussi, au moins sur VS2005, 'WCHAR' est un typedef pour' wchar_t', pas 'unsigned short'. – casablanca

1

Windows ne sait rien de wchar_t, car wchar_t est un concept de programmation. Réciproquement, wchar_t est juste stockage, et il ne sait rien sur la valeur sémantique des données que vous y stockez (c'est-à-dire, il ne sait rien sur Unicode ou ASCII ou autre.)

Si un compilateur ou SDK qui cible Windows définit wchar_t étant 16 bits, alors ce compilateur peut être en conflit avec le standard C++ 0x. (Je ne sais pas s'il existe des clauses get-out qui permettent à wchar_t d'avoir 16 bits.) Mais dans tous les cas, le compilateur peut définir wchar_t comme 32 bits (pour se conformer à la norme) et fournir des fonctions d'exécution/de UTF-16 pour quand vous devez passer votre wchar_t * aux API Windows.

Questions connexes