Sind diese beiden Stile der C-Funktionszeigerdefinition unterschiedlich?

8

Ich habe mich zufällig dabei ertappt, dass ich zwei verschiedene Arten von C-Funktionszeiger-Definitionen an verschiedenen Stellen verwendet habe und habe beschlossen, ein minimales Programm zu schreiben, um diese Unterschiede zu testen.

Die beiden folgenden Stile sind:

%Vor%

und

%Vor%

Ich habe ein minimales Programm geschrieben, das beide Stile für den gleichen Funktionszeiger verwendet, einen für die Deklaration einer Funktion und einen für die Definition derselben Funktion , um zu sehen, was der Compiler darüber zu sagen hätte.

Erklärung:

%Vor%

Definition:

%Vor%

Wie Sie (hoffentlich) sehen können, habe ich für den ersten Parameter in der Deklaration den Stil int (*a_fn)() verwendet, während ich in der Definition der Funktion den Stil int (a_fn ()) verwendet habe. Ich mache etwas ähnliches mit den nächsten beiden Argumenten.

Ich spekulierte, dass diese Typen möglicherweise inkompatibel sind, dass diese Stile den Unterschied zwischen einer Pass-by-Reference- und einer Pass-by-Value-Zuweisung der Variablen ausmachen könnten, aber als ich dieses Programm kompilierte, kompilierte der Compiler es lautlos . Keine Fehler, keine Warnungen, nichts.

Da ich sehr viele Tutorials gesehen habe, die für den zweiten Stil plädieren, während ich persönlich den ersten Stil aus ästhetischen Gründen bevorzuge, interessiert mich, worin der Unterschied zwischen diesen beiden Stilen besteht und welcher empfohlen wird.

Vollständiger Codebeispiel:

%Vor%     
Marcus Harrison 10.03.2016, 17:23
quelle

2 Antworten

4

In einer Funktionsparameterliste werden Funktionen in Funktionszeiger umgewandelt. Der C11-Standard, ISO / IEC 9899: 2011, §6.7.6.3 Funktionsdeklaratoren (einschließlich Prototypen) sagt:

  

¶8 Eine Deklaration eines Parameters als "Funktionsrückgabetyp" soll angepasst werden an "Zeiger auf Funktionsrückgabetyp" ...

Also, wie beschrieben, werden die Parameter alle als "Zeiger auf Funktion" behandelt. Es ist jedoch am besten, selbstkonsistent zu sein.

Beachten Sie, dass eine Funktion keine Funktion zurückgeben kann:

  

¶1 Ein Funktionsdeklarator darf keinen Rückgabetyp angeben, der ein Funktionstyp oder ein Array-Typ ist.

Außerhalb eines Funktionsdeklarators (der Argumentliste einer Funktionsdefinition oder Funktionsdeklaration) unterscheiden sich die Notationen:

%Vor%

Der erste deklariert (definiert) eine Variable mit dem Namen a_fn - ein Zeiger auf eine Funktion, die int mit einer nicht spezifizierten (aber nicht variablen) Argumentliste zurückgibt.

Die zweite erklärt die Existenz einer Funktion namens b_fn , die eine int mit einer nicht spezifizierten (aber nicht variadischen) Argumentliste zurückgibt (und eine überflüssige Menge Klammern hat; sie könnte int b_fn(); und geschrieben werden es bedeutet dasselbe).

    
Jonathan Leffler 10.03.2016, 17:31
quelle
2

Sowohl int (comp (int)) als auch int (*comp)(int) sind äquivalent, wenn sie als Funktionsparameter verwendet werden. Funktionsbezeichner werden in Zeiger auf die Funktion selbst umgewandelt.

C11-§6.3.2.1:

  

Ein Funktionsbezeichner ist ein Ausdruck mit einem Funktionstyp. Außer wenn es der Operand des sizeof Operators, des _Alignof Operators, 65) oder des unären & Operators ist, wird ein Funktionsbezeichner mit dem Typ "function returning type" in ein umgewandelt Ausdruck, der den Typ "Zeiger auf Funktion, die Typ zurückgibt" hat.

    
haccks 10.03.2016 17:29
quelle

Tags und Links