2012-02-25 17 views
8

¿Cómo (en GCC/"GNU C") declara un puntero de función que apunta a una función __attribute__((const))? La idea es que quiero que el compilador evite generar múltiples llamadas a la función llamada a través del puntero de función cuando puede almacenar en caché el valor de retorno de una llamada anterior.Puntero de función para __tribuir __ ((const)) función?

+0

nunca he hecho eso y casi quedarse dormido con la investigación, pero trate de envolver una llamada por la dirección de una función de este tipo con función declarada explícitamente que tiene el atributo const y acepta que el puntero como un parámetro. Si gcc puede determinar que la dirección del puntero y los argumentos no cambian, debería eliminar las llamadas innecesarias. –

+1

@Vlad: Pensé en eso también, pero luego gcc se rehúsa a alinear la función en los casos en que yo quiera. Originalmente tenía una función de envoltura así, pero la eliminé para corregir el comportamiento de alineación. En caso de que sea interesante, la función en cuestión es '((pthread_t (*) (void)) 0xffff0fe0)' (la función Linux-ARM get-thread-puntero). –

+0

Pregunta interesante. ¿La respuesta de justin tuvo el resultado deseado? – Praxeolitic

Respuesta

3
typedef void (*t_const_function)(void) __attribute__((const)); 

static __attribute__((const)) void A(void) { 
} 

static void B(void) { 
} 

int main(int argc, const char* argv[]) { 
    t_const_function a = A; 

    // warning: initialization makes qualified 
    // function pointer from unqualified: 
    t_const_function b = B; 

    return 0; 
} 

O simplemente:

__attribute__((const)) void(*a)(void) = A; 
+0

Bleh, 'typedef' siempre es la solución cuando tienes un tipo de puntero a función desagradable. Aceptado. Pero ¿hay alguna idea de si hay una forma de escribir el reparto en mi comentario sobre la pregunta principal sin un 'typedef'? –

+0

@R. Desafortunadamente, no * sé * cómo enrollarlo todo en una declaración sin un 'typedef' - no parece ser posible en GCC 4.2. '((__attribute __ ((const)) pthread_t (*) (void)) 0xffff0fe0)' es como creo que se haría, pero se interpreta de forma diferente a lo que desea (parece que GCC aplica el atributo al tipo de devolución, no la función). – justin

0

Aunque esto no es exactamente la respuesta a su pregunta, usted probablemente querrá saber esto:

No es posible en el caso general esperar que el compilador para realizar la optimización se puede esperar aquí. El compilador no puede, en el caso general, realizar el análisis de alias necesario para saber que los usos múltiples de un puntero a función corresponden a la misma función.

Una llamada de función entre dos invocaciones de la función a través del puntero podría, en el caso general, alterar los contenidos del puntero, haciendo que la función invocada sea diferente en la segunda llamada.

Debido a la naturaleza de C, realizar un análisis de alias adecuado a menudo no es posible resolverlo, por lo que no es probable que ocurra este tipo de optimización.

+2

Eso es lo que __attribute __ ((const)) hace - le dice al compilador que usted conoce mejor y le da luz verde para ciertas optimizaciones. –

+0

En mi caso, puede saberlo, porque el puntero es un literal de dirección (un entero convertido a un puntero de función). Ver los comentarios. –

+2

@Vlad: Creo que el punto de Perry era que incluso si la función apuntada es 'const', el compilador también debería asegurarse de que el * puntero * no cambiara entre invocaciones. Pero eso no es demasiado difícil de determinar, y en mi caso no es posible, ya que es una dirección literal absoluta. –

Cuestiones relacionadas