Conversion invalide de char non signé * en char *

Voici un code –

1 int main(int argc, char *argv[]) 2 { 3 signed char S, *psc; 4 unsigned char U, *pusc; 5 char C, *pc; 6 7 C = S; 8 C = U; 9 10 pc = psc; 11 pc = pusc; 12 13 return 0; 14 } $ gcc test.cpp -oa test.cpp: In function 'int main(int, char**)': test.cpp:10:7: error: invalid conversion from 'signed char*' to 'char*' [-fpermissive] test.cpp:11:7: error: invalid conversion from 'unsigned char*' to 'char*' [-fpermissive] 

Ceci est compilé sur la version 4.6.3 de gcc sur Ubuntu 12.10 sur une machine Intel 32 bits.

Considérant que le type de caractère est unsigned char sur x86.

Si les affectations sur les lignes 7 et 8 pour les types sans pointeur sont correctes, pourquoi des erreurs sont-elles générées pour les types de pointeurs sur les lignes 10 et 11?

De plus, C = U réussir sans nécessiter de transtypage?

Tout d’abord, il est important de souligner le fait que char , signed char et unsigned char sont tous des types différents . La section 4.10 de la norme C ++ 11 définit les trois conversions de pointeurs standard possibles entre des pointeurs de types différents:

1 . Une constante de pointeur nulle est une valeur constante d’expression constante (5.19) de type entier évaluée à zéro ou de type std :: nullptr_t. Une constante de pointeur null peut être convertie en un type de pointeur; le résultat correspond à la valeur de pointeur null de ce type et se distingue de toutes les autres valeurs de type pointeur d’object ou de fonction. Une telle conversion s’appelle une conversion de pointeur nul. Deux valeurs de pointeurs nulles du même type doivent être comparées égales. La conversion d’une constante de pointeur null en pointeur de type qualifié cv est une conversion unique et non la séquence d’une conversion de pointeur suivie d’une conversion de qualification (4.4). Une constante de pointeur null de type intégral peut être convertie en une valeur de type std :: nullptr_t. [Remarque: la valeur prvalue résultante n’est pas une valeur de pointeur nulle. —Fin note]

Ce n’est pas pertinent, car nous n’avons pas de pointeurs nuls de type nulltptr_t ici.

2 Une valeur de type “pointeur sur cv T”, où T est un type d’object, peut être convertie en une valeur de type “pointeur sur cv void”. Le résultat de la conversion d’un “pointeur sur cv T” en un “pointeur sur cv void” pointe vers le début de l’emplacement de stockage où réside l’object de type T, comme s’il s’agissait de l’object le plus dérivé (1.8) de type T (c’est-à-dire pas un sous-object de classe de base). La valeur du pointeur null est convertie en la valeur du pointeur null du type de destination.

Cela ne peut pas s’appliquer, car le type de destination n’est pas void . Finalement,

3 Une valeur de type “pointeur sur cv D”, où D est un type de classe, peut être convertie en une valeur de type “pointeur sur cv B”, où B est une classe de base (clause 10) de D. Si B est un classe de base de D inaccessible (Article 11) ou ambigu (10.2), un programme qui nécessite cette conversion est mal formé. Le résultat de la conversion est un pointeur sur le sous-object de classe de base de l’object de classe dérivé. La valeur du pointeur null est convertie en la valeur du pointeur null du type de destination.

signed char n’est pas une classe de base de char , donc même cela ne s’applique pas.

Par conséquent, une conversion implicite et standard de pointeur de caractère signed char en caractère ne peut pas être effectuée.

Par ailleurs, les conversions entre les valeurs de types intégraux sont autorisées conformément à ce qui est spécifié au paragraphe 4.7.

C ++ n’a pas de conversion automatique de pointeur, quels que soient les types de pointeur de chaque côté de l’affectation; s’ils sont différents, vous avez besoin d’un transtypage.

char est un type distinct de unsigned char et signed char . Il n’est garanti que la représentation de valeur équivalente à l’un d’eux, mais il s’agit toujours d’un type distinct. Par conséquent, vous ne pouvez convertir ni unsigned char* non unsigned char* ni unsigned char* signed char* en char* (c’est-à-dire, sauf si vous utilisez un reinterpret_cast ). C ++ ne permet tout simplement pas les conversions de pointeurs entre types distincts, car un type peut se faire passer pour un autre.

Toutefois, une conversion de caractère non unsigned char ou de caractère signed char en caractère convient parfaitement, car elle implique simplement une conversion de sa valeur.

Considérez-le de cette façon: vous pouvez convertir un int en float , mais vous ne pouvez pas convertir un int* en float* .

Je peux me tromper, mais comme dit plus haut, lorsque vous avez affecté “C = S; C = U;”, C ++ le convertit automatiquement, un peu comme si vous le faisiez “char x =” h “; printf (“% i “, x ); “. Toutefois, les pointeurs pointent vers un emplacement spécifique en mémoire et cet emplacement a une taille. Ainsi, lors de la conversion, il suffit de regarder les valeurs sous différents angles, mais pointer des valeurs différentes peut impliquer de changer la taille de la valeur sur laquelle on pointe.