2017-09-01 2 views
0

Considérons:C++ de manière portable pour obtenir la représentation de la valeur d'une chaîne de U8 littérale

char const str[] = u8"ñ"; 
auto const* u8_code_units = reinterpret_cast<unsigned char*>(str); 
// using u8_code_units elements 

Est-ce entièrement portable et C++ conforme à la norme? Ou y a-t-il une clause qui dit que c'est un comportement indéfini ou qui dépend de n'importe quelle valeur non spécifiée? Je sais que unsigned char et char auront les mêmes exigences d'alignement et reinterpret_cast<T*>(v) est égal à static_cast<T*>(static_cast<void*>(v)), donc, je pense qu'il est complètement sûr et portable pour l'utiliser, mais je ne suis pas sûr.

Répondre

2

Est-ce totalement portable et conforme à la norme C++?

Un peu, mais pas pour la raison que vous en pensez.

Voir, vous devez réellement enregistrer ce fichier sur le disque dans un certain format. Ce qui signifie que votre compilateur doit pouvoir lire ce même format. Et quels formats de texte un compilateur prend en charge est défini par l'implémentation.

Toutefois, si votre compilateur prend en charge le format dans lequel vous l'avez enregistré et que ce format peut enregistrer des caractères codés en Unicode, alors votre compilateur fera ce qu'il faut.

Même le reinterpret_cast est très bien, car le compilateur exige que char tableaux sont accessibles à partir unsigned char tableaux, même si la signature char de la plate-forme. Et la norme exige explicitement que, lors de la lecture d'un tableau char au format UTF-8 via un unsigned char, vous obtiendrez les bits que vous attendez de la mise en forme UTF-8.

Notez cependant:

Je sais que unsigned char et le charbon ont les mêmes exigences d'alignement et reinterpret_cast (v) égal dans ce cas à static_cast (static_cast (v)),

Cela ne suffirait pas à vous protéger. Cela fonctionne parce que la norme explicitement dit que cela fonctionne dans ce cas particulier, pas à cause des exigences d'alignement et autres. char et unsigned char ont des exceptions aux règles sur l'aliasing pour permettre cela; l'alignement n'a rien à voir avec cela.

+0

l'exigence d'alignement est nécessaire pour s'assurer que la conversion de 'void *' à 'T2' renvoie le même emplacement de mémoire que' t2' avant 'static_cast (t2)'. C'est pourquoi je l'ai remarqué. Et merci de me signaler la chose "alias". J'ai googlé et j'ai déjà trouvé cette exception stricte d'aliasing dans la norme (3.10§10). –

+0

Question connexe: est-ce la seule façon de lire les octets sous-jacents? –

+0

@ Peregring-lk: Vous pouvez juste le lire comme 'char's. La norme garantit que, dans la plage 'unsigned char' 0-255, il existe un mappage 1: 1 aux valeurs' char'. Donc, si vous convertissez la valeur 0x80 en un 'char', il est garanti de comparer l'égalité à la valeur' unsigned char' de 0x80. Bien sûr, si vous voulez faire un peu de bidouillage pour les opérations UTF-8, vous aurez besoin de les lire comme 'char non signé. –