Kann ein Funktionsprototyp typedef in Funktionsdefinitionen verwendet werden?

Lesezeit: 3 Minuten

Benutzeravatar von bitmask
Bitmaske

Ich habe eine Reihe von Funktionen mit demselben Prototyp, sagen wir

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

Nun möchte ich ihre Definition und Deklaration vereinfachen. Natürlich könnte ich ein solches Makro verwenden:

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

Aber ich möchte es in C behalten, also habe ich versucht, den Speicherbezeichner zu verwenden typedef dafür:

typedef int SpFunc(int a, int b);

Dies scheint für die Deklaration gut zu funktionieren:

SpFunc func1; // compiles

aber nicht für die Definition:

SpFunc func1 {
  // ...
}

was mir folgenden Fehler gibt:

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

Gibt es eine Möglichkeit, dies richtig zu machen, oder ist es unmöglich? Nach meinem Verständnis von C sollte dies funktionieren, tut es aber nicht. Wieso den?


Beachten Sie, gcc versteht, was ich versuche zu tun, denn wenn ich schreibe

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

es sagt mir

error: function 'func1' is initialized like a variable

Das bedeutet, dass gcc versteht, dass SpFunc ein Funktionstyp ist.

Sie können eine Funktion nicht mit einer Typedef für einen Funktionstyp definieren. Es ist ausdrücklich verboten – siehe 6.9.1/2 und die zugehörige Fußnote:

Der in einer Funktionsdefinition deklarierte Bezeichner (der der Name der Funktion ist) muss einen Funktionstyp haben, wie durch den Deklaratorteil der Funktionsdefinition angegeben.

Die Absicht ist, dass die Typkategorie in einer Funktionsdefinition nicht von einer Typedef geerbt werden kann:

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

  • Ich hatte Angst davor. Danke für die Bestätigung. Gibt es dafür eine Begründung? Es scheint mir ein nützliches Feature zu sein.

    – Bitmaske

    1. Januar 2011 um 17:54 Uhr

  • @bitmask: Funktionen können sich eine Typedef teilen, aber anders benannte Argumente haben – die Namen sind nicht Teil der Funktionssignatur und können sogar weggelassen werden, wenn die Deklaration nicht Teil der Definition ist

    – Christoph

    1. Januar 2011 um 18:32 Uhr

Benutzeravatar von user541686
Benutzer541686

EIN typedef definiert a Typ, kein Header (der Quellcodetext ist). Sie müssen verwenden #define (obwohl ich es nicht empfehle), wenn Sie den Code für den Header ausklammern müssen.

([Edited] Der Grund, warum das erste funktioniert, ist, dass es keinen Prototyp definiert – es definiert eine Variable des Typs, der durch definiert wird typedefwas Sie nicht wollen.)

  • Nein, das ist nicht der Typ eines Zeigers. Das wäre typedef int (*SpFunc)(int a, int b);. Und da die Deklaration gültig ist, handelt es sich um einen richtigen Funktionstyp. Die Frage ist, warum ich es nicht für die Definition verwenden kann.

    – Bitmaske

    1. Januar 2011 um 17:51 Uhr

  • Ups, Entschuldigung, ich habe das Fehlen des Sternchens nicht gesehen. Danke für die Korrektur.

    – Benutzer541686

    1. Januar 2011 um 17:54 Uhr

  • Worauf ist das eine Antwort? Es ist die einzige Erwähnung von “Header” auf der Seite.

    – Jim Balter

    8. Oktober 2017 um 3:02 Uhr

  • @JimBalter: Es ist eine Antwort auf die Frage. Er versucht, eine Typedef als Funktionsheader zu verwenden. Ich sage, es ist nicht möglich, weil eine Typedef einen Typ definiert, keinen Header.

    – Benutzer541686

    8. Oktober 2017 um 3:07 Uhr


  • Das heißt, es erklärt, warum die Sprachsyntax nicht geändert werden kann, um sie zuzulassen type name {body}, was eine wünschenswerte Änderung wäre, wenn es möglich wäre. Ihre ist eine dieser lästigen Antworten auf “Warum kann ich das nicht tun”, die einfach sagt “Sie können es nicht tun” (während Sie dem OP etwas vortragen, was sie bereits wissen), als ob die Sprachdefinition eine unveränderliche rohe Tatsache wäre des Universums ohne Reim oder Grund.

    – Jim Balter

    8. Oktober 2017 um 7:11 Uhr


1390950cookie-checkKann ein Funktionsprototyp typedef in Funktionsdefinitionen verwendet werden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy