Asignar la dirección propia de un int a su valor

3 minutos de lectura

avatar de usuario
Yuval

¿El siguiente código tiene un comportamiento indefinido, implementación definida o definida por el estándar? No pude encontrar ninguna referencia sobre la asignación de un número entero a su propia dirección.

volatile int x = (int)&x;

Este código se traduce a:

lea         eax,[ebp-4]  
mov         dword ptr [ebp-4],eax 

  • Creo que esto se reduce a cómo se maneja la conversión de direcciones a números enteros. El hecho de que esté almacenado en el propio número entero, creo, no tiene ninguna consecuencia.

    – templatetypedef

    11 de noviembre de 2013 a las 19:44

  • El valor de x se definirá la implementación, siempre que int es al menos tan ancho como int *; como cada vez que usas reinterpret_cast pasar de un puntero a un int.

    – Avakar

    11 de noviembre de 2013 a las 19:44


  • Yo diría que está definida por la implementación. En algunas plataformas, un int es posible que no pueda retener el valor del puntero (dirección). Por ejemplo, un sistema de palabras de 16 bits con direccionamiento de 24 bits.

    – Thomas Matthews

    11 de noviembre de 2013 a las 19:44

  • ¿El famoso estándar C/C++?

    – Pascal Cuoq

    11 de noviembre de 2013 a las 19:44

  • @DieterLücking Esto no es un duplicado. Estoy preguntando sobre el comportamiento del compilador cuando asigna a un número entero local su propia dirección, mientras que la pregunta que está señalando trata sobre proporcionar la dirección como argumento para una función.

    – Yuval

    11 de noviembre de 2013 a las 19:53

En C, usando x tanto en la declaración como en la inicialización está bien:

(C99, 6.2.1p7) “[…] Cualquier otro identificador tiene un alcance que comienza justo después de la finalización de su declarador”.

El resultado de la conversión del puntero al entero está definido por la implementación y puede tener un comportamiento indefinido:

(C99, 6.3.2.3p7) “Cualquier tipo de puntero se puede convertir en un tipo de número entero. Salvo que se especifique lo contrario, el resultado está definido por la implementación. Si el resultado no se puede representar en el tipo de número entero, el comportamiento no está definido. El resultado no necesita estar en el rango de valores de ningún tipo entero”.

avatar de usuario
masud

En C++, de acuerdo con el regla del punto de declaración. Está bien definido. porque antes =La variable x se declara y luego &x es conocida. Aquí hay un punto complicado, el siguiente código es comportamiento indefinido:

int x = x;        // undefined behavior, using uninitialized variable

pero…

int x = (int)&x;  // defined behavior

Estoy hablando de C++, pero creo que también es válido para C.

avatar de usuario
Atlético

En el código ASM que muestra, el valor del puntero se pone primero en eaxy luego el puntero se lee de eax y poner en la misma ubicación que el valor del número entero.

El único problema aquí es que un int no siempre es del mismo tamaño que un int*. En mi máquina de 64 bits, intLos s son 4 bytes y los punteros son 8 bytes. Si hubiera ejecutado su código en mi caja, obtendría solo la mitad del puntero.

¿Ha sido útil esta solución?