tipos reinterpret_cast que conversion c++ char reinterpret-cast static-cast unsigned-char

reinterpret_cast - conversion c++



¿Por qué no puedo static_cast entre char*y unsigned char*? (3)

Además de ser punteros, unsigned char * y char * no tienen nada en común (EdChum ya mencionó el hecho de que char , signed char y unsigned char son tres tipos diferentes). Podría decir lo mismo para los tipos de punteros Foo * y Bar * para cualquier estructura diferente.

static_cast significa que un puntero del tipo de fuente puede usarse como un puntero del tipo de destino, que requiere una relación de subtipo. Por lo tanto, no puede usarse en el contexto de su pregunta; lo que necesita es reinterpret_cast que hace exactamente lo que quiere o un elenco de estilo C.

Aparentemente, el compilador los considera tipos no relacionados y, por lo tanto, se requiere reinterpret_cast . ¿Por qué es esta la regla?


Son tipos completamente diferentes, ver estándar:

3.9.1 Tipos fundamentales [basic.fundamental]

1 Los objetos declarados como caracteres char) deben ser lo suficientemente grandes como para almacenar cualquier miembro del conjunto de caracteres básicos de la implementación. Si un carácter de este conjunto se almacena en un objeto de carácter, el valor integral de ese objeto de carácter es igual al valor de la forma literal de un solo carácter de ese carácter. Se define en la implementación si un objeto char puede contener valores negativos. Los caracteres se pueden declarar explícitamente sin firmar o
firmado. Plain char, signed char y unsigned char son tres tipos distintos. Un char, un char firmado y un char sin signo ocupan la misma cantidad de almacenamiento y tienen los mismos requisitos de alineación ( basic.types ); es decir, tienen la misma representación de objeto. Para los tipos de caracteres, todos los bits del objeto
la representación participa en la representación del valor. Para los tipos de caracteres sin signo, todos los patrones de bits posibles de la representación del valor representan números. Estos requisitos no son válidos para otros tipos. En cualquier implementación particular, un objeto de carbonilla simple puede tomar los mismos valores que un char firmado o un char sin signo; cuál es definido por la implementación.

De manera análoga a esto, también es la razón por la cual falla lo siguiente:

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

b son tipos completamente diferentes, realmente lo que se cuestiona es por qué static_cast es tan restrictivo cuando puede realizar lo siguiente sin problema

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

y ¿por qué no puede deducirse que los tipos de objetivos tienen el mismo ancho de campo de bits y se pueden representar? Puede hacer esto para los tipos escalares pero para los punteros, a menos que el objetivo se derive de la fuente y desee realizar un downcast, entonces, el lanzamiento entre punteros no va a funcionar.

Bjarne Stroustrop static_cast por qué los static_cast son útiles en este enlace: http://www.stroustrup.com/bs_faq2.html#static-cast pero en forma abreviada, es para que el usuario static_cast claramente cuáles son sus intenciones y para dar el compilador la oportunidad de verificar que lo que está intentando lograr se puede lograr, ya que static_cast no admite el static_cast entre diferentes tipos de punteros, entonces el compilador puede detectar este error para alertar al usuario y si realmente quieren hacer esta conversión, entonces deben usar reinterpret_cast .


está intentando convertir punteros no relacionados con static_cast. Eso no es para lo que está static_cast. Aquí puede ver: Tipo Casting .

Con static_cast puede convertir datos numéricos (por ejemplo, char a unsigned char debería funcionar) o puntero a clases relacionadas (relacionadas por alguna herencia). Este no es el caso. Desea convertir un puntero no relacionado en otro, por lo que debe usar reinterpret_cast.

Básicamente, lo que estás tratando de hacer es que el compilador sea lo mismo que tratar de convertir un carácter * en un vacío *.

Ok, aquí algunos pensamientos adicionales por qué permitir esto es fundamentalmente erróneo. static_cast se puede usar para convertir tipos numéricos entre sí. Por lo tanto, es perfectamente legal escribir lo siguiente:

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

lo que también es posible:

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

Si observa este código en ensamblador, verá que el segundo molde no es una mera reinterpretación del patrón de bits de d, sino que se insertan aquí algunas instrucciones de ensamblador para conversiones.

Ahora, si ampliamos este comportamiento a las matrices, el caso en el que basta con una forma diferente de interpretar el patrón de bits, podría funcionar. Pero, ¿qué pasa con el lanzamiento de matrices de dobles en matrices de ints? Ahí es donde tienes que declarar que simplemente quieres una reinterpretación de los patrones de bits; hay un mecanismo para eso llamado reinterpret_cast, o debes hacer un trabajo extra. Como puede ver, la extensión simple de static_cast para puntero / matrices no es suficiente, ya que necesita comportarse de manera similar a los valores únicos de static_casting de los tipos. Esto a veces necesita un código adicional y no se puede definir claramente cómo se debe hacer para las matrices. En su caso, deteniéndose en / 0, porque es la convención? Esto no es suficiente para casos que no sean cadenas (número). ¿Qué sucederá si el tamaño del tipo de datos cambia (por ejemplo, int frente a doble en x86-32bit)?

El comportamiento que desea no se puede definir correctamente para todos los casos de uso, es por eso que no está en el estándar de C ++. De lo contrario, tendría que recordar cosas como: "puedo convertir este tipo en otro siempre que sean de tipo entero, tengan el mismo ancho y ...". De esta manera, es totalmente claro, ya sea que se trate de CLASES relacionadas, luego puede lanzar los indicadores, o son tipos numéricos, entonces puede emitir los valores.