2011-01-01 6 views
26

Ich habe eine Reihe von Funktionen mit dem gleichen Prototyp, sageKann ein Funktionsprototyp typedef in Funktionsdefinitionen verwendet werden?

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

Nun, ich mag ihre Definition und Erklärung vereinfachen. Natürlich könnte ich einen Makro so verwenden:

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

Aber ich mag es in C halten, so dass ich versuchte, den Speicherspezifikations typedef für diesen Einsatz:

typedef int SpFunc(int a, int b); 

Dies scheint darauf hinzu gut funktionieren für die Erklärung:

SpFunc func1; // compiles 

aber nicht für die Definition:

SpFunc func1 { 
    // ... 
} 

, die mir die folgende Störung gibt:

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

Gibt es eine Möglichkeit, dies richtig zu tun oder ist es unmöglich? Zu meinem Verständnis von C sollte dies funktionieren, aber es nicht. Warum?


Hinweis, versteht gcc, was ich zu tun versuchen, weil, wenn ich

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

schreiben erzählt es mir

error: function 'func1' is initialized like a variable 

Was bedeutet, dass gcc versteht, dass SpFunc eine Funktion ist Art.

Antwort

39

Sie können nicht Definieren Sie eine Funktion mit einem typedef für einen Funktionstyp. Es ist ausdrücklich verboten - siehe 6.9.1/2 und die dazugehörige Fußnote:

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

Ich hatte Angst davor. Danke, dass du das bestätigt hast. Gibt es dafür Gründe? Es scheint mir ein nützliches Feature zu sein. – bitmask

+7

@bitmask: Funktionen können eine typedef teilen, haben aber unterschiedlich benannte Argumente - die Namen sind nicht Teil der Funktionssignatur und können sogar weggelassen werden, wenn die Deklaration nicht Teil der Definition ist – Christoph

0

Ein typedef definiert einen Typ, keine Kopfzeile (das ist Quelltext). Sie müssen #define verwenden (obwohl ich es nicht empfehle), wenn Sie den Code für den Header herausfiltern müssen.

([Edited] Der Grund für die erste funktioniert, ist, dass es nicht einen Prototyp definiert, -. Eine Variable vom Typ der typedef definiert ist zu definieren, die nicht das, was Sie wollen)

+1

Nein, dies ist nicht der Typ eines Zeigers. Das wäre 'typedef int (* SpFunc) (int a, int b); Und da die Deklaration gültig ist, ist es ein richtiger Funktionstyp. Die Frage ist, warum ich es nicht für die Definition verwenden kann. – bitmask

+0

Oops sorry, habe das Fehlen des Sterns nicht gesehen. Danke für die Korrektur. – Mehrdad

+0

Was ist das für eine Antwort? Es ist die einzige Erwähnung von "Header" auf der Seite. –