2009-10-30 16 views
13

En this SO hilo, Brian Postowsuggested una solución que implica falsos funciones anónimas:funciones anónimas falsas en C

hacer un borrador (L) función que devuelve la versión del borrador para las matrices de longitud L ... de esa manera L se convierte en un parámetro, no en un elemento global

¿Cómo implemento una función de este tipo?

+0

No creo que sea necesario proporcionar un enlace a la página superior de stackoverflow.com en su pregunta. –

+0

La pregunta a la que se vincula es acerca de cómo hacerlo en C++. Esta pregunta está etiquetada C. ¿De qué quieres saber? –

+0

La solución que Barry proporcionó está en C. La mayoría de los comentarios sugirieron que no es posible resolver mi primera pregunta en C++. – Alexandru

Respuesta

6

Consulte the answer I just posted a esa pregunta. Puede usar la biblioteca callback(3) para generar nuevas funciones en tiempo de ejecución. No es compatible con los estándares, ya que implica muchos hacks específicos de la plataforma, pero funciona en una gran cantidad de sistemas.

La biblioteca se ocupa de asignar memoria, asegurarse de que la memoria sea ejecutable y de enjuagar la caché de instrucciones si es necesario para garantizar que el código generado dinámicamente (es decir, el cierre) sea ejecutable. En esencia, genera talones de código que podría tener este aspecto en x86:

pop %ecx 
    push $THUNK 
    push %ecx 
    jmp $function 
THUNK: 
    .long $parameter 

Y a continuación, devuelve la dirección de la primera instrucción. Lo que hace este stub es almacenar la dirección de retorno en ECX (un registro reutilizable en la convención de llamadas x86), empuja un parámetro extra en la pila (un puntero a un procesador) y luego vuelve a presionar la dirección de retorno. Luego, salta a la función real. Esto hace que la función se deje engañar al pensar que tiene un parámetro extra, que es el contexto oculto del cierre.

En realidad es más complicado que eso (la función real llamada al final del código es __vacall_r, no la función en sí, y __vacall_r() maneja más detalles de implementación), pero ese es el principio básico.

+0

¿Qué hay del rendimiento de esta solución? – Pacerier

1

No es posible generar funciones normales durante el tiempo de ejecución en C o C++. Lo que Brian sugirió se basa en un gran "si": "... si puede falsificar funciones anónimas ...". Y la respuesta a ese "si" es: no, no puedes. (Aunque no está claro lo que quería decir con "falso".)

(En C++ es posible generar objetos de tipo función en tiempo de ejecución, pero no las funciones ordinarias.)

Lo anterior se aplica a la norma C y C++. Las implementaciones particulares pueden admitir varias extensiones proporcionadas por la implementación y/o hacks implementados manualmente, como "cierres", "delegados" y cosas similares. Nada de eso, por supuesto, tiene algo que ver con los lenguajes estándar de C/C++.

2

No creo que pueda hacer eso con C99 - no hay ninguna aplicación parcial o instalación de cierre disponible a menos que comience a generar manualmente código de máquina en tiempo de ejecución.

Los bloques recientemente propuestos de Apple funcionarían, aunque necesita el soporte del compilador para eso. Here's a brief overview of blocks. No tengo idea de cuándo/si algún proveedor externo a Apple los admitirá.

+0

El compilador de clang admite bloques, aparentemente porque Apple financia el proyecto. – mcandre

Cuestiones relacionadas