Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

171
Views
¿Cómo puede una variable tomar la dirección de sí misma dentro de su propia declaración?

Considera esto:

 void* x = &x; printf("%p\n", x);

Sorprendentemente, compila y se ejecuta con la salida:

7ffb2f7248

¿Cómo es posible que x tome la dirección de sí mismo cuando x aún no se ha creado?

Editar: tenga en cuenta que en este caso no hay ambigüedad presente con respecto a su asignación, lo que deja en claro qué es exactamente lo que se cuestiona.

over 4 years ago · Santiago Trujillo
5 answers
Answer question

0

Está combinando la asignación y la inicialización.

El almacenamiento se asigna para x simplemente porque esta declaración define su existencia. La inicialización es un paso separado que sigue a la asignación de almacenamiento. Debido a esto, la dirección de x puede conocerse durante su propia inicialización.

(Tenga en cuenta que un puntero de este tipo no se puede desreferenciar de forma segura hasta que el valor apuntado se haya inicializado, pero no hay razón por la que la dirección no se pueda tomar antes de la inicialización).

over 4 years ago · Santiago Trujillo Report

0

¿Cómo es posible que x tome la dirección de sí mismo cuando x aún no se ha creado?

Porque no es necesario que un objeto exista para saber dónde se creará.

over 4 years ago · Santiago Trujillo Report

0

Muy simple. La dirección de los objetos de duración de almacenamiento estático es conocida por el enlazador que llena todas las direcciones.

Las variables de almacenamiento automático que no están optimizadas y se usa su dirección son fáciles de calcular para el compilador.

https://godbolt.org/z/e84xM3

over 4 years ago · Santiago Trujillo Report

0

Esta respuesta es para la etiqueta C.

La expresion:

 void* x = &x;

es un declarador de inicio que es declarador = inicializador

Esto se puede encontrar en la sección 6.7 de N1570 (borrador de la norma C) y 6.7.6 dice:

Un declarante completo es un declarante que no forma parte de otro declarante. El final de un declarador completo es un punto de secuencia.

Y 6.2.1/7 dice:

Las etiquetas de estructura, unión y enumeración tienen un alcance que comienza justo después de la aparición de la etiqueta en un especificador de tipo que declara la etiqueta. ...<algún texto no citado>... Cualquier otro identificador tiene un alcance que comienza justo después de la finalización de su declarador.

Estas secciones indican que el objeto se crea antes de que se inicialice. En consecuencia, el inicializador puede utilizar la dirección del objeto creado.

En la sección 6.3.2.3 Punteros:

Un puntero a void puede convertirse en o desde un puntero a cualquier tipo de objeto . Un puntero a cualquier tipo de objeto se puede convertir en un puntero para anular y viceversa; el resultado se comparará igual al puntero original.

Por lo tanto, dado que cualquier puntero se puede convertir en un puntero vacío, la dirección de x se puede asignar a un puntero vacío.

Así que para tu código:

Primero se crea el objeto y luego se inicializa.

 void* x = &x; ^^^^^^^ ^^^^^ | | | step 2: initialize object | step 1: create object, ie end of full declarator

Para este código es más o menos lo mismo que una tarea.

 void* x; // Create x = &x; // Assignment instead of initialization // But in this case it works just the same
over 4 years ago · Santiago Trujillo Report

0

C++ 2018 6.3.2 [basic.scope.pdecl] 1 dice:

El punto de declaración de un nombre es inmediatamente después de su declarador completo (Cláusula 11) y antes de su inicializador (si lo hay), excepto como se indica a continuación.

Los elementos "anotados a continuación" no se aplican aquí, por lo que, en void* x = &x; , x se declara después de la primera x (que es el declarador ) y antes de = &x (el inicializador ), por lo que se puede hacer referencia a x en el inicializador, esencialmente como si el código fuera void *x; x = &x; .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!