Namespaces
Variants

Function definitions

From cppreference.net

Eine Funktionsdefinition verknüpft den Funktionsrumpf (eine Folge von Deklarationen und Anweisungen) mit dem Funktionsnamen und der Parameterliste. Im Gegensatz zur Funktionsdeklaration sind Funktionsdefinitionen nur im Dateigültigkeitsbereich erlaubt (es gibt keine geschachtelten Funktionen).

C unterstützt zwei verschiedene Formen von Funktionsdefinitionen:

attr-spec-seq (optional) specifiers-and-qualifiers parameter-list-declarator function-body (1)
specifiers-and-qualifiers identifier-list-declarator declaration-list function-body (2) (bis C23)

wo

attr-spec-seq - (C23) eine optionale Liste von Attributen , angewendet auf die Funktion
specifiers-and-qualifiers - eine Kombination aus
parameter-list-declarator - ein Deklarator für einen Funktionstyp, der eine Parameterliste verwendet, um Funktionsparameter zu bezeichnen
identifier-list-declarator - ein Deklarator für einen Funktionstyp, der eine Bezeichnerliste verwendet, um Funktionsparameter zu bezeichnen
declaration-list - eine Folge von Deklarationen, die jeden Bezeichner in identifier-list-declarator deklarieren. Diese Deklarationen können keine Initialisierer verwenden und der einzige erlaubte Speicherklassenspezifizierer ist register .
function-body - ein Verbundstatement , also eine in geschweiften Klammern eingeschlossene Folge von Deklarationen und Anweisungen, die bei jedem Aufruf dieser Funktion ausgeführt wird
1) Definition von Funktionen im neuen Stil (C89). Diese Definition führt sowohl die Funktion selbst ein und dient gleichzeitig als Funktionsprototyp für alle zukünftigen Funktionsaufrufausdrücke , wobei sie Konvertierungen von Argumentausdrücken zu den deklarierten Parametertypen erzwingt.
int max(int a, int b)
{
    return a>b?a:b;
}
double g(void)
{
    return 0.1;
}
2) (bis C23) Alte (K&R) Funktionsdefinition. Diese Definition verhält sich nicht wie ein Prototyp und alle zukünftigen Funktionsaufrufausdrücke führen Standard-Argumentpromotionen durch.
int max(a, b)
int a, b;
{
    return a>b?a:b;
}
double g()
{
    return 0.1;
}

Inhaltsverzeichnis

Erklärung

Wie bei Funktionsdeklarationen muss der Rückgabetyp der Funktion, bestimmt durch den Typspezifizierer in specifiers-and-qualifiers und möglicherweise modifiziert durch den declarator wie üblich in Deklarationen , ein vollständiger Nicht-Array-Objekttyp oder der Typ void sein. Wenn der Rückgabetyp cvr-qualifiziert wäre, wird er für die Konstruktion des Funktionstyps auf seine unqualifizierte Version angepasst.

void f(char *s) { puts(s); } // Rückgabetyp ist void
int sum(int a, int b) { return a+b; } // Rückgabetyp ist int
int (*foo(const void *p))[3] { // Rückgabetyp ist Zeiger auf Array von 3 int
    return malloc(sizeof(int[3]));
}

Wie bei Funktionsdeklarationen werden die Typen der Parameter von Funktionen zu Zeigern und von Arrays zu Zeigern angepasst, um den Funktionstyp zu konstruieren, und die Top-Level-cvr-Qualifizierer aller Parametertypen werden für die Bestimmung des kompatiblen Funktionstyps ignoriert.

Im Gegensatz zu Funktionsdeklarationen sind unbenannte formale Parameter nicht zulässig (andernfalls gäbe es Konflikte bei alten (K&R) Funktionsdefinitionen). Sie müssen benannt werden, selbst wenn sie innerhalb der Funktion nicht verwendet werden. Die einzige Ausnahme ist die spezielle Parameterliste ( void ) .

(bis C23)

Formale Parameter können in Funktionsdefinitionen unbenannt sein, da alte (K&R) Funktionsdefinitionen entfernt wurden. Unbenannte Parameter sind innerhalb des Funktionskörpers nicht über ihren Namen zugreifbar.

(seit C23)
int f(int, int); // Deklaration
// int f(int, int) { return 7; } // Fehler bis C23, OK seit C23
int f(int a, int b) { return 7; } // Definition
int g(void) { return 8; } // OK: void deklariert keinen Parameter

Im Funktionsrumpf ist jeder benannte Parameter ein lvalue -Ausdruck; sie haben automatische Speicherdauer und Blockgültigkeitsbereich . Die Speicheranordnung der Parameter (oder ob sie überhaupt im Speicher abgelegt werden) ist nicht spezifiziert: Sie ist Teil der Aufrufkonvention .

int main(int ac, char **av)
{
    ac = 2; // Parameter sind Lvalues
    av = (char *[]){"abc", "def", NULL};
    f(ac, av);
}

Weitere Einzelheiten zur Funktionsweise eines Funktionsaufrufs finden Sie unter Funktionsaufruf-Operator und Informationen zum Verlassen von Funktionen unter return .

__func__

In jedem Funktionsrumpf ist die spezielle vordefinierte Variable __func__ mit Blockgültigkeit und statischer Speicherdauer verfügbar, als wäre sie unmittelbar nach der öffnenden Klammer definiert durch:

static const char __func__[] = "function name";

Dieser spezielle Bezeichner wird manchmal in Kombination mit den vordefinierten Makrokonstanten __FILE__ und __LINE__ verwendet, zum Beispiel durch assert .

(seit C99)

Hinweise

Die Argumentliste muss explizit im Deklarator vorhanden sein, sie kann nicht von einem typedef geerbt werden

typedef int p(int q, int r); // p ist ein Funktionstyp int(int, int)
p f { return q + r; } // Fehler

In C89 war specifiers-and-qualifiers optional, und wenn es weggelassen wurde, war der Rückgabetyp der Funktion standardmäßig int (möglicherweise geändert durch den declarator ).

Zusätzlich erforderte die alte Definitionsweise keine Deklaration für jeden Parameter in declaration-list . Jeder Parameter, dessen Deklaration fehlte, hatte den Typ int

max(a, b) // a and b have type int, return type is int
{
    return a>b?a:b;
}
(bis C99)

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C-Standards angewendet.

DR Applied to Behavior as published Correct behavior
DR 423 C89 der Rückgabetyp könnte qualifiziert sein der Rückgabetyp wird implizit disqualifiziert

Referenzen

  • C17-Standard (ISO/IEC 9899:2018):
  • 6.9.1 Funktionsdefinitionen (S: 113-115)
  • C11-Standard (ISO/IEC 9899:2011):
  • 6.9.1 Function definitions (p: 156-158)
  • C99-Standard (ISO/IEC 9899:1999):
  • 6.9.1 Funktionsdefinitionen (S: 141-143)
  • C89/C90-Standard (ISO/IEC 9899:1990):
  • 3.7.1 Funktionsdefinitionen

Siehe auch

C++ Dokumentation für Funktionsdefinition