2016-05-31 14 views
4

Ich verstehe, dass typedef verwendet werden, kann einen neuen benutzerdefinierten Typen zu definieren, zum Beispiel:komplizierter Typedef in C++

// simple typedef 
typedef unsigned long ulong; 

// the following two objects have the same type 
unsigned long l1; 
ulong l2; 

ich vor kurzem über diese typedef kam und ging verloren zu entziffern, was in der Erklärung wird :

typedef int16_t CALL_CONVENTION(* product_init_t)(product_descript_t *const description) 

jemand mich leiten kann und erklären, was das tut?

BEARBEITEN: NEW_TYPE in CALL_CONVENTION geändert. Es ist eine Definition. Danke, dass du das herausgefunden hast.

+2

Es deklariert einen Alias ​​des Funktionszeiger-Typs. Siehe http://stackoverflow.com/questions/4295432/typedef-function-pointer. – kennytm

+0

Ich würde lieber sagen 'typedef int16_t (* stuff) (Zeug) NEW_TYPE;' – ForceBru

+1

Was ist 'NEW_TYPE'? ist das ein '# define'? –

Antwort

8

Es Typ product_init_t als Zeiger erklärt, auf eine Funktion, die

  • Parameter nimmt product_descript_t *const description;
  • gibt int16_t zurück;
  • verwendet Aufruf Konvention CALL_CONVENTION (wie @ M.M vorgeschlagen, auch wenn es falsch benannt wurde).

P. S. Da „eine vollständige Antwort im Jahr 2016 sollte die moderne Art und Weise zeigt diesen type-alias zu schreiben“ (@Howard Hinnant), hier ist es:

using product_init_t = int16_t (CALL_CONVENTION *)(product_descript_t *const description); 
+2

ist es wahrscheinlich, dass' NEW_TYPE' ist eine Bindung oder Aufrufkonvention Spezifizierer definieren; nicht ein Teil des Rückgabetyps –

+1

@ M.M Wahrscheinlich, aber dann ist der Name etwas verwirrend. Wie auch immer, zu der Antwort hinzugefügt. Vielen Dank! – AlexD

+0

@ M.M Sie haben Recht. Ich habe den Schnitt zum Post gemacht. – nikk

2

Hier ist, wie Sinn komplizierter typedefs zu machen: Erstens Blick auf der Linie mit typedef entnommen:

int16_t NEW_TYPE (* product_init_t)(product_descript_t *const description); 

Dann herausfinden, was diese Linie würde erklären: es ist eine Variable product_init_t mit einer bestimmten Art genannt.

Schließlich typedef hinzufügen bedeutet, dass es product_init_t zu einem Alias ​​für diesen bestimmten Typ anstelle einer Variablen dieses Typs erklärt.


Um die obige Erklärung zu erarbeiten, Sie cdecl verwenden können, oder Sie können in von außen unter Verwendung der Kenntnis der möglichen Deklaratoren (Zeiger, ein Array-Funktion) aus dem Angriff zu nehmen.

In diesem Fall ist das äußerste Feature die Parameterliste auf der rechten Seite, also vermuten wir, dass dies ein Funktionsdeklarator sein könnte. Funktionsdeklaratoren aussehen (grob):

returntype function_name (parameters_opt) 

obwohl bedenken Sie, dass eine gemeinsame Compiler-Erweiterung ist zu additonal Eigenschaften der Funktion über __declspec oder auf andere Weise, an der gleichen Stelle wie der Rückgabetyp angeben; oder es könnte extern "C" dort sein, und so weiter.

Bis jetzt sind wir in der Phase, (*product_init_t) ist eine Funktion mit int16_t NEW_TYPE als Rückgabetyp (und mögliche declspecs) und Parameterliste (product_descript_t *const description).

Schließlich ist * product_init_t nur ein Zeiger Deklarator, so dass wir schließen, dass product_init_t ein Zeiger auf eine Funktion des obigen Typs ist.

Ihre Kommentare weisen darauf hin, unsicher über NEW_TYPE. Es wird etwas sein, das bereits früher definiert wurde (oder ein Compiler-Erweiterungsschlüsselwort); vielleicht würde die Vorverarbeitung des Codes mit gcc -E helfen, wenn Ihre IDE ihre Definition nicht finden kann.

+0

Die richtige Linie ist 'typedef int16_t CALL_CONVENTION (* product_init_t) (product_descript_t * const Beschreibung)' wo CALL-CONVENTION in 'ifdef definiert ist __amd64__ definieren CALL_CONVENTION sonst CALL_CONVENTION __attribute __ ((__ cdecl__)) endif' wie wird diese definieren jetzt einen Unterschied machen? – nikk

1

Es ist ein interessantes Beispiel für den Unterschied zwischen #define und typedef Verwendung.

#define FX_TYPE void (*)(int) 
typedef void (*stdfx)(int); 

void fx_typ(stdfx fx); /* ok */ 
void fx_def(FX_TYPE fx); /* error */ 

siehe here

daher bei folgenden:

typedef int16_t CALL_CONVENTION(* product_init_t)(product_descript_t *const description) 

Wir haben die oben typedef verwenden können wie folgt:

void fx_typ(product_init_t fx); 

fx ist ein Zeiger auf Funktion, die nimmt product_descript_t *const description als Argument und r Eurns int16_t.

Die Verwendung von CALL_CONVENTION ist verwirrend, aber es kann durch leere Makro unterdrückt werden, wie folgt:

#define CALL_CONVENTION 

Hinweis: Das oben genannte Mikro keinen Körper hat. Aus meiner Sicht, CALL_CONVENTION nur zur Verwirrung beiträgt.

+0

Guter Punkt, @vivek. CALL CONVENTION ist in meinem Beispiel tatsächlich (in den meisten Fällen) leer. Ich frage mich, worum es geht. – nikk