¿Qué significa ' ((void (*) ()) 0x1000) ();`? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Aquí hay un código cuyo propósito es configurar el contador del programa para saltar a la dirección 0x1000. Sé lo que hace, pero no entiendo cómo. Está relacionado con mi falta de conocimiento del idioma C. Quizá puedas iluminarme. Aquí está el declaración / función (incluso no sé lo que es:))

((void (*)())0x1000)();

Lo que es puntero a una función que devuelve void y no acepta ningún argumento. Por favor corrígeme si me equivoco.

Author: Cool Guy, 2015-05-20

4 answers

C las declaraciones se decodifican de adentro hacia afuera usando una regla simple: comience desde el identificador y verifique en el lado derecho [] (matriz) o () (función) luego verifique en el lado izquierdo el tipo de los valores (almacenados en la matriz o devueltos por la función), sin cruzar los paréntesis; escape de los paréntesis y repita.

Por ejemplo:

void (*p)()

p es (nada a la derecha) un puntero (a la izquierda, no cruce los paréntesis) a (escape los paréntesis, lea el siguiente nivel) una función (derecha) que no devuelve nada (izquierda).

Cuando falta el identificador (p en este caso), todo lo que queda es una declaración de tipo.

Un tipo encerrado entre paréntesis, puesto delante de un valor es un tipo fundido.

(void (*)())0x1000

Convierte el número 0x1000 en un puntero a una función que no devuelve nada (vea lo que está fuera de los paréntesis en el párrafo sobre la declaración de p anterior).

En el siguiente nivel, la expresión anterior (un puntero a una función se puede usar de la misma manera que un nombre de función) se usa para ejecutar el código apuntado.

Ver abajo toda la expresión de-compuesta:

(
  (
    void (*)()   /* type: pointer to function that doesn't return anything     */
  )0x1000        /* value 0x1000 treated as a value of the type declared above */
)                /* enclose in parentheses to specify the order of evaluation  */ 
();              /* the pointer above used as a function name to run the code  */
 44
Author: axiac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-20 11:04:24

(void (*)()) es un puntero a una función que devuelve void y toma un número de argumentos no especificado, pero fijo.

(void (*)())0x1000 es fundiendo el literal 0x1000 al tipo anterior.

Finalmente, el sufijo () llama a esa función. La expresión anterior que necesita estar entre paréntesis de lo contrario el sufijo () se unirá al 0x1000 que no es sintácticamente válido.

Depende de usted comprobar si el casting es realmente válido. Si no, entonces el el comportamiento de su programa es indefinido.

 17
Author: Bathsheba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-20 10:38:08

Una constante

0x1000

Se lanza a un tipo:

(type)0x1000

El tipo es void (*)() - un puntero (asterisco) a una función que no toma parámetros (paréntesis vacíos a la derecha) (oops, ver el comentario de pmg) y no devuelve ningún valor (void a la izquierda). Paréntesis adicionales en el asterisco evitan asociarlo a void, lo que crearía incorrectamente un tipo void * aquí.

Así que después del cast tienes un puntero a una función void sin parámetros en las direcciones 0x1000:

(void (*)())0x1000

Y esa función...

((void (*)())0x1000)

Se llama añadiendo una lista de parámetros vacía:

((void (*)())0x1000)();
 13
Author: CiaPan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:25:22

La persona que escribió ese código debería haberlo reescrito de una manera legible como:

#define ADDRESS_OF_FUNCTION_X 0x1000

typedef void (*func_ptr_t)(void);

...

func_ptr_t function_x = (func_ptr_t)ADDRESS_OF_FUNCTION_X;
function_x();

Lo que hace el código ahora está casi auto-documentado.

 5
Author: Lundin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-20 11:15:31