2010-04-29 24 views

Respuesta

21

El resultado de la conversión de tipo es siempre un valor p . No se puede asignar Rvalue, por lo que su primera expresión no se compila. No se puede tomar la dirección de Rvalue, por lo que su segunda expresión no se compila.

Con el fin de realizar la conversión de tipo correcto, usted tiene que a ella de la siguiente manera

p = (char *) &l; 

Ésta es la forma correcta de hacer lo que ha intentado hacer en su segunda expresión. Convierte el puntero int * al tipo char *.

Su primera expresión es irreparable.Se puede hacer

*(int **) &p = &l; 

pero lo que hace que al final no es realmente una conversión , sino más bien reinterpretación de la memoria ocupada por char * puntero como int * puntero. Es un truco ilegal feo que la mayoría de las veces tiene muy poco valor práctico.

+0

hey idont entiende su tipeo (int **) ,,,, qué significado tiene (int **) –

+0

Puntero-a-puntero. Como se dice en esa respuesta, es solo un truco feo. –

+0

gracias por la ayuda –

6

La forma correcta de hacer esto sería:

int I = 65; 
char* p = (char*)&I; 

&I le da una int* que apunta a I; a continuación, transfiéralo a char* y asígnelo al p.

Tenga en cuenta que normalmente no debería emitir entre punteros de tipos no relacionados. Sin embargo, se puede usar un char* para acceder a cualquier objeto, por lo que en este caso particular es seguro.

+0

Específicamente, de acuerdo con C99 6.3.2.3.7, el comportamiento de convertir un puntero de un tipo en un puntero de un tipo diferente no está definido solo si los punteros en cuestión tienen alineamientos diferentes. Continúa diciendo que cuando un puntero a un objeto se convierte en un puntero al tipo de carácter, el resultado apunta al byte direccionado más bajo del objeto. – dreamlax

+0

@dreamlax: En realidad, estaba pensando en C99 §6.5/7, que detalla las reglas de aliasing. La conversión de punteros puede no conducir a resultados indefinidos, pero el acceso al objeto apuntado puede. –

0

En C simple, que no es tan estricto para escribir conversiones, este código se compilaría y realmente funcionaría. En un compilador de C++, en realidad requeriría conversiones explícitas como ya se mencionó (ver otras respuestas).

+1

No, tampoco funciona en la zona C. El resultado de un operador de reparto es como el resultado de '+' - no se puede hacer '& ((char) l)' por la misma razón que no se puede hacer '& (a + b)'. – caf

+0

Hm. No sé por qué, pero msvs2008 compila este código y la depuración muestra que realmente funciona. Extraño. –

3

(int *) p = & l;

La línea anterior no funciona, porque en cuanto a que lances p (int *), el resultado es un objeto temporal anónima, que es un rvalue y no un lvalue; en consecuencia, el resultado no puede recibir la asignación, e incluso si el lenguaje lo permitiera, estaría asignando una copia temporal de p, no a la p original.

p = & ((char) l);

La línea anterior no funciona por una razón similar; el resultado de (char) l es un objeto temporal que es una copia de l casted al tipo char. En consecuencia, como es temporal, no se puede tomar su dirección.

Insead, que puede utilizar:

p = (char*) &l 
0

El problema es que cuando estás interpretando los moldes (aparte de si el tipo de casting que estás haciendo es una buena idea o no) es que la expresión de cast resulta en un valor r.

No se pueden asignar valores a los valores ni se han tomado sus direcciones.

Cuestiones relacionadas