2011-01-01 8 views
26

que tienen una serie de funciones con el mismo prototipo, dicen¿Se puede usar un prototipo de función typedef en las definiciones de funciones?

int func1(int a, int b) { 
    // ... 
} 
int func2(int a, int b) { 
    // ... 
} 
// ... 

Ahora, yo quiero para simplificar su definición y la declaración. Por supuesto que podría utilizar una macro de esa manera:

#define SP_FUNC(name) int name(int a, int b) 

Pero me gustaría mantenerlo en C, por lo que trató de utilizar el especificador de almacenamiento typedef para esto:

typedef int SpFunc(int a, int b); 

Esto parece trabajar bien para la declaración:

SpFunc func1; // compiles 

pero no para la definición:

SpFunc func1 { 
    // ... 
} 

que me da el siguiente error:

error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token 

¿Hay una manera de hacer esto correctamente, o es imposible? Para mi comprensión de C esto debería funcionar, pero no es así. ¿Por qué?


Nota, gcc entiende lo que estoy tratando de hacer, porque, si escribo

SpFunc func1 = { /* ... */ } 

me dice

error: function 'func1' is initialized like a variable 

Lo que significa que gcc entiende que SpFunc es una función tipo.

Respuesta

39

No se puede define una función usando un typedef para un tipo de función. Está explícitamente prohibido - se refieren a 6.9.1/2 y la nota asociada:

The identifier declared in a function definition (which is the name of the function) shall have a function type, as specified by the declarator portion of the function definition.

The intent is that the type category in a function definition cannot be inherited from a typedef:

typedef int F(void); // type F is "function with no parameters 
        // returning int" 
F f, g; // f and g both have type compatible with F 
F f { /* ... */ } // WRONG: syntax/constraint error 
F g() { /* ... */ } // WRONG: declares that g returns a function 
int f(void) { /* ... */ } // RIGHT: f has type compatible with F 
int g() { /* ... */ } // RIGHT: g has type compatible with F 
F *e(void) { /* ... */ } // e returns a pointer to a function 
F *((e))(void) { /* ... */ } // same: parentheses irrelevant 
int (*fp)(void); // fp points to a function that has type F 
F *Fp; //Fp points to a function that has type F 
+0

Tenía miedo de esto. Gracias por confirmar esto. ¿Hay alguna razón para esto? Me parece una característica útil. – bitmask

+7

@bitmask: las funciones pueden compartir un typedef, pero tienen argumentos con nombres diferentes: los nombres no son parte de la firma de la función e incluso se pueden omitir si la declaración no es parte de la definición – Christoph

0

A typedef define un tipo, no una cabecera (que es fuente de texto de código). Debe usar #define (aunque no lo recomiendo) si necesita factorizar el código para el encabezado.

([Editado] La razón por la que funciona el primero de ellos es que no es la definición de un prototipo -. Se define una variable de tipo definido por el typedef, que no es lo que desea)

+1

No, esto no es del tipo de un puntero. Eso sería 'typedef int (* SpFunc) (int a, int b);'. Y dado que la declaración es válida, es un tipo de función adecuado. La pregunta es por qué no puedo usarlo para la definición. – bitmask

+0

Vaya, lo siento, no vi la falta del asterisco. Gracias por la corrección. – Mehrdad

+0

¿Qué es esto una respuesta? Es la única mención de "encabezado" en la página. –

Cuestiones relacionadas