2012-01-16 27 views
10

Tengo una función static inline definido en un archivo H, y en un momento en un fichero C, estoy asignación de un puntero a la función, algo como esto:C: puntero a función en línea

foo.h :

static inline void frobnicate(void) { 
    // frobs something. 
} 

foo.c

#include "foo.h" 

void execute(void (*func)(void)) { 
    func(); 
} 

void blahBlahBlah(void) { 
    execute(frobnicate); 
} 

bar.c

#include "foo.h" 
// ... 
frobnicate(); 

Así que creo que lo que sucederá aquí es que el compilador alineará la llamada a frobnicate desde bar.c, pero en foo.c, en realidad tendrá que crear una función para implementar frobnicate, para que pueda tener un funcionamiento puntero a ella.

¿Alguien puede confirmar si mi comprensión es correcta y corregirme de lo contrario?

+2

* Usted * puede confirmarlo, leyendo el código generado. No creo que haya una forma específica en que este * tiene * que funcionar. No me sorprendería que el compilador diga "alguien quiere la dirección de esto, así que no lo intentemos, entonces". – unwind

+7

Recuerde que 'inline' es solo una _sugerencia_ para el compilador –

Respuesta

10

inline es uno de los nombres incorrectos del estándar C. Su significado principal es poder poner la definición de una función en un archivo de encabezado sin tener que lidiar con problemas de "definición múltiple" en el tiempo del enlace.

La manera oficial en C99 y C11 para hacer lo que quiere lograr es tener la definición inline en el archivo de encabezado, sin el static. Como también necesita que se emita el símbolo, debe indicarle al compilador en qué unidad de compilación debería estar. Dicha instanciación se puede realizar con una declaración en ese archivo .c donde omite la palabra clave inline.

Lo más natural es que podría usar el archivo .c donde realmente necesita el símbolo.

+0

Si la definición en línea está en el archivo de encabezado sin 'static', ¿entonces no tendré varias definiciones del mismo nombre (la función en línea) cuando intento vincular? – brianmearns

+0

Tendrá problemas de vinculación. Haga que sea 'estático en línea' y arriesgue múltiples definiciones, o renuncie a la línea.También puede hacer un contenedor, que estará en un archivo C y no estará en línea, y tomar un puntero al mismo (sin rendimiento, porque la función real se insertará en el contenedor). – ugoren

+0

@bmearns, con un compilador compatible con C99 no tendrá ningún problema de vinculación. Este es exactamente el sentido de la palabra clave 'inline'. http://gustedt.wordpress.com/2010/11/29/myth-and-reality-about-inline-in-c99/ –

7

Sí, tienes razón. Cuando toma el puntero a la función, el compilador debe crear una versión "independiente" donde el código se puede llamar como una función normal.

El beneficio de subrayar una función es que no es necesario crear el código de llamada y se puede aplicar cualquier otra optimización para integrar tanto la función de llamador como la función en línea. Pero cuando necesita hacer una llamada regular a la función (como cuando toma la dirección para llamarla más tarde), esas optimizaciones ya no son posibles.

+2

Esto puede ser cierto para muchos compiladores, pero no puedo imaginar por qué se requeriría un compilador para hacerlo. El ejemplo de la OP podría incluirse con bastante facilidad incluso en el caso del puntero de la función. –

+0

'inline' es una recomendación. Si el compilador no puede alinearse, no lo hará, y si no puede, aún así puede decidir no hacerlo (y puede alinearse incluso sin la palabra clave 'inline'). Los punteros de función generalmente evitan la creación de líneas, aunque en este caso el compilador puede darse cuenta de que no (o no molestar). – ugoren

+0

Sí, en este caso sería posible alinear la función. Supuse que esta era una versión simplificada del problema. Pero tienes razón. – Governa

Cuestiones relacionadas