Pourquoi ne puis-je pas static_cast entre char * et unsigned char *?

Apparemment, le compilateur considère qu’il s’agit de types non liés et donc, reinterpret_cast est requirejs. Pourquoi est-ce la règle?

Ils sont complètement différents types voir standard:

3.9.1 Types fondamentaux [basic.fundamental]

1 Les objects déclarés comme caractères char) doivent être suffisamment grands pour stocker tout membre du jeu de caractères de base de la mise en oeuvre. Si un caractère de cet ensemble est stocké dans un object de caractère, la valeur intégrale de cet object de caractère est égale à la valeur de la forme littérale à caractère unique de ce caractère. Il est défini par l’implémentation si un object char peut contenir des valeurs négatives. Les caractères peuvent être explicitement déclarés non signés ou
signé. Les caractères simples, les caractères signés et les caractères non signés sont trois types distincts. Un caractère, un caractère signé et un caractère non signé occupent la même quantité de stockage et ont les mêmes exigences d’alignement ( basic.types ); c’est-à-dire qu’ils ont la même représentation d’object. Pour les types de caractères, tous les bits de l’object
la représentation participe à la représentation de la valeur. Pour les types de caractères non signés, tous les modèles de bits possibles de la représentation de valeur représentent des nombres. Ces exigences ne sont pas valables pour les autres types. Dans toute implémentation particulière, un object plain char peut prendre les mêmes valeurs qu’un caractère signé ou un caractère non signé; lequel est défini par la mise en œuvre.

Si analogue à cela est également pourquoi l’échec suivant:

 unsigned int* a = new unsigned int(10); int* b = static_cast(a); // error different types 

a et b sont des types complètement différents, vous vous demandez vraiment pourquoi static_cast est si ressortingctif quand il peut effectuer les opérations suivantes sans problème

 unsigned int a = new unsigned int(10); int b = static_cast(a); // OK but may result in loss of precision 

et pourquoi ne peut-on pas en déduire que les types de cible ont la même largeur de champ de bits et peuvent être représentés? Cela peut être fait pour les types scalaires mais pour les pointeurs, à moins que la cible ne soit dérivée de la source et que vous souhaitiez effectuer un downcast, la conversion entre pointeurs ne fonctionnera pas.

Bjarne Stroustrop explique pourquoi les static_cast sont utiles dans ce lien: http://www.stroustrup.com/bs_faq2.html#static-cast mais sous forme abrégée, il appartient à l’utilisateur d’indiquer clairement ses intentions et de donner au Le compilateur a la possibilité de vérifier que ce que vous avez l’intention de réaliser peut être réalisé. static_cast ne prend pas en charge la diffusion entre différents types de pointeurs, le compilateur peut intercepter cette erreur pour alerter l’utilisateur. static_cast souhaite réellement effectuer cette conversion, il doit utiliser reinterpret_cast .

vous essayez de convertir des pointeurs indépendants avec un static_cast. Ce n’est pas ce que fait static_cast. Ici vous pouvez voir: Type Casting .

Avec static_cast, vous pouvez convertir des données numériques (par exemple, un caractère en caractère non signé devrait fonctionner) ou un pointeur vers des classes associées (liées par un inheritance). Ce n’est pas le cas. Vous voulez convertir un pointeur indépendant en un autre, vous devez donc utiliser reinterpret_cast.

Essentiellement, vous essayez de faire en sorte que le compilateur tente de convertir un caractère * en vide *.


Ok, voici quelques reflections supplémentaires sur le fait de permettre cela est fondamentalement faux. static_cast peut être utilisé pour convertir des types numériques en un autre. Donc, il est parfaitement légal d’écrire ce qui suit:

 char x = 5; unsigned char y = static_cast(x); 

ce qui est également possible:

 double d = 1.2; int i = static_cast(d); 

Si vous examinez ce code dans assembleur, vous constaterez que la deuxième conversion n’est pas une simple réinterprétation du modèle de bits de d, mais que certaines instructions de l’assembleur relatives aux conversions sont insérées ici.

Maintenant, si nous étendons ce comportement aux tableaux, dans le cas où une manière différente d’interpréter le modèle de bits serait suffisante, cela pourrait fonctionner. Mais qu’en est-il des tableaux de doublons à des tableaux d’ints? C’est là que vous devez déclarer que vous souhaitez simplement réinterpréter les modèles de bits – il existe un mécanisme pour cela appelé reinterpret_cast, ou vous devez effectuer un travail supplémentaire. Comme vous pouvez le constater, l’extension de static_cast pour les pointeurs / tableaux n’est pas suffisante, car elle doit se comporter de la même manière que static_casting avec des valeurs uniques des types. Cela nécessite parfois du code supplémentaire et la manière dont cela doit être fait pour les tableaux n’est pas clairement définie. Dans votre cas – arrêt à \ 0 – parce que c’est la convention? Ceci n’est pas suffisant pour les cas non-chaîne (nombre). Que se passera-t-il si la taille du type de données change (par exemple int vs double sur x86-32bit)?

Le comportement souhaité ne peut pas être défini correctement pour tous les cas d’utilisation, c’est pourquoi il ne figure pas dans la norme C ++. Sinon, vous devez vous rappeler des choses telles que: “Je peux transtyper ce type à l’autre tant qu’il est de type entier, de même largeur et …”. De cette façon, il est tout à fait clair – ou bien ce sont des CLASSES liées – vous pouvez alors lancer les pointeurs, ou ce sont des types numériques – puis vous pouvez transtyper les valeurs.

En plus d’être des pointeurs, unsigned char * et char * n’ont rien en commun (EdChum a déjà mentionné le fait que char , signed char et unsigned char sont de trois types différents). Vous pouvez dire la même chose pour les types de pointeur Foo * et Bar * à toutes les structures dissemblables.

static_cast signifie qu’un pointeur du type source peut être utilisé en tant que pointeur du type de destination, ce qui nécessite une relation de sous-type. Par conséquent, il ne peut pas être utilisé dans le contexte de votre question. ce dont vous avez besoin est soit reinterpret_cast qui fait exactement ce que vous voulez, soit une dissortingbution dans le style C.