2010-04-09 19 views
6

ellos dijeron esta expresión es válida en C, y que significa llamar a una función:de desciframiento (* (void (*)()) 0)()

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

Puede alguien explicar claramente lo que este medio de expresión ?

He intentado compilar esto y me sorprendió que no haya resultado en un error.

+2

Extraño llamar a esto una función oculta. –

+0

"No es un comportamiento indefinido ... ¡es una característica!". No, es un comportamiento indefinido –

Respuesta

18

Paso a paso:

void(*)()  // a pointer-to-function type, taking unspecified parameters 
        // and returning nothing. 
    (void(*)())0  // a null pointer of that pointer-to-function type 
(*(void(*)())0)  // dereference that pointer 
(*(void(*)())0)(); // and call it with no parameters 

El código ha indefinido comportamiento, que va probablemente se cuelgue con algún tipo de acceso/segfault ilegal.

+0

@Steve Jessop: gracias por los detalles respuesta – NguyenDat

+2

En realidad, ese código tendría un comportamiento específico para la plataforma que lo está compilando. Puede estar claramente definido para algunas plataformas e ilegal para otras. Compré un microcontrolador recientemente, y cuando está activado, ejecuta código comenzando en la dirección 0 en la memoria. Entonces ese código saltaría al comienzo del programa. – Ponkadoodle

+2

Bien, ese microcontrolador es uno de los casos, lo que significa que solo * probablemente * falla - la probabilidad de que nguyendat use una plataforma donde no es baja ;-) Cuando digo "comportamiento indefinido", por supuesto me refiero , como siempre, indefinido por el estándar C Las implementaciones particulares pueden garantizar lo que harán en casos particulares de comportamiento indefinido. –

6

Está creando un puntero a una función y luego llamándola. No lo llamaría una característica oculta sino un comportamiento indefinido.

Básicamente lo que están haciendo esto, pero con la dirección 0 en su lugar:

void test() { } 

void(*pfn)() = test; 
(*pfn)(); 
3

Es un puntero a una función en NULL.

void(*)() es la definición de un puntero a una función que no toma argumentos que no devuelve nada; puede que el nombre:

typedef void(*my_func)(); 

continuación, en su ejemplo usted tiene un reparto:

(my_func)0 produce un puntero a una función my_func, es decir, una función de tomar nada y devolver nada.

Luego lo desreferenciamos con el asterisco inicial (que es innecesario, afaik), y luego lo llama.

Así que está llamando a una función que no toma argumentos y no devuelve nada de lo que le sucede a la vida en la dirección cero.

Esto es (por lo general) un comportamiento indefinido, y se bloqueará instantáneamente en muchas plataformas. (No es un comportamiento indefinido si se pone una función en la dirección cero, al menos yo no creo que era.)

2

Desglose por paréntesis.

La última () significa una función sin parámetros.

La línea (void(*)()) significa una función que devuelve vacío.

La última poco, la (* al principio y al 0) es decirle al compilador que la dirección de la función para llamar a la mentira en la ubicación del puntero 0.

Así que, básicamente, todo lo que está llamando diablos se encuentra en dirección 0 sin parámetros. No suele ser muy seguro. :)

0

en un entorno incrustado, podría ser una forma de llamar a la rutina de restablecimiento del sistema.

Cuestiones relacionadas