2017-05-24 16 views
2

Ich versuche, Funktionsdeklaration mit typedefs zu verstehen.Typedef Funktion vs Funktionszeiger

Was macht dieser Code in C++?

typedef void fcn_t(void); 
typedef void (*ptr_t)(void); 

fcn_t f; 
fcn_t *pf; 
ptr_t pf2; 

In meinem Verständnis:

  • fcn_t ist der Typ einer Funktion, so dass die Linie mit f ist eine Funktion Erklärung (keine Definition), und ich konnte es später definieren wie void f(void) { blabla(); bleble(); } als ob ich void f(void); anstelle von fcn_t f; deklariert hätte;
  • fcn_t * ist der Typ eines Funktionszeigers und die Linie mit pf ist eine Zeigervariable Definition und pf ist default-initialisiert (der Codeauszug unter der Annahme von dem globalen Bereich ist);
  • Es gibt keinen Unterschied zwischen fcn_t* und ptr_t, also alles, was ich über pf gesagt habe, gilt für pf2.

Habe ich es richtig gemacht? Hat eine der drei Deklarationen ihre Bedeutung geändert, wenn ich sie als extern markiert habe? Was würde sich ändern, wenn der Code als C anstatt als C++ kompiliert würde?

+0

wo Sie 'ptr_f' definiert haben? – arboreal84

+0

btw Ich schlage dringend das folgende Tutorial vor: http://www.newty.de/fpt/fpt.html#defi – arboreal84

+1

1. yes, 2. 'pf' wird auf Nullzeiger initialisiert (wenn global), 3. ja 4. Mit 'extern' auf' pf' wäre es eine Deklaration und keine Definition. 5. C und C++ sind in der Regel kompiliert, nicht interpretiert –

Antwort

2

Ja, Sie sind in allen drei Punkten richtig. Die einzige Sache, die sich ändern würde, wenn Sie sie extern markierten, sind die Funktionszeiger. Funktionsdeklarationen sind standardmäßig extern in C++.

Versuchen und kompilieren Sie das folgende Programm

template <typename...> 
struct WhichType; 

typedef void fcn_t(void); 
typedef void (*ptr_t)(void); 

// constexpr auto one = WhichType<fcn_t>{}; 
// constexpr auto two = WhichType<fcn_t*>{}; 
// constexpr auto three = WhichType<ptr_t>{}; 

fcn_t f; 

void f() {} 

int main() { 
    f(); 
} 

uncommenting die kommentierten Zeilen werden Sie wahrscheinlich einen Compiler-Fehler geben, der Ihnen sagt, welche Arten der WhichType Instanz mit instanziiert wird, und als Ergebnis sollte es zeigen Ihnen die genaue Typen aller drei Dinge, nach denen du gefragt hast. Es ist ein Trick, den ich in Scott Meyers Buch "Effective Modern C++" gefunden habe.


Um zu testen, ob die Erklärungen sind extern oder nicht, zwei einfache Implementierung Dateien schreiben, mit einer der Definition der Variablen

main.cpp

template <typename...> 
struct WhichType; 

typedef void fcn_t(void); 
typedef void (*ptr_t)(void); 

fcn_t f; 

int main() { 
    f(); 
} 

Definition enthält. cpp

void f() {} 

und dann kompilieren, verknüpfen und ausführen definition.cpp und main.cpp (über g++ -std=c++14 definition.cpp main.cpp und dann ./a.out). Wenn die Deklaration nicht extern war, würde die Kompilierung mit einem undefinierten Symbolfehler fehlschlagen.

+1

Ich habe es versucht! Ich wollte nur wissen, ob das Standard C++ war oder mein GCC war einfach nett zu mir :) – fonini

+1

@fonini - Es ist Standard C++ (und C zufällig) – StoryTeller

-1

Hier ist eine einfache Darstellung dieser typedef

#include <stdio.h> 

typedef void fcn_t(void); 
typedef void (*ptr_t)(void); 

fcn_t f; 
fcn_t *pf; 
ptr_t pf2; 

void 
f(void) 
{ 
    printf("I am void\n"); 
} 

void 
vSayHi(void) 
{ 
    printf("Hi\n"); 
} 

int 
main(void) 
{ 

    pf2 = vSayHi; 
    pf2(); 

    pf = vSayHi; 
    pf(); 

    f(); 

    return 0; 
} 

OUTPUT:

Hi 
Hi 
I am void