Frage

Setup

Ich habe ein paar Fragen zu den Standardaktionen Argument, wenn eine Funktion in C aufrufen Hier Abschnitt 6.5.2.2 „Funktionsaufrufe“ Die Absätze 6, 7 und 8 von der C99-Standard (pdf) (Hervorhebung hinzugefügt und in Listen für eine einfache Lesung gebrochen):

Ziffer 6

  
      
  1. Wenn der Ausdruck, der die genannte Funktion bezeichnet einen Typ hat, dass enthält keinen Prototyp sind die Integer-Promotions auf jedes Argument ausgeführt und Argumente, die Art float haben, werden gefördert double. Diese sind die default Argument Aktionen genannt .
  2.   
  3. Wenn die Anzahl der Argumente nicht die Anzahl der Parameter nicht gleich, das Verhalten ist nicht definiert.
  4.   
  5. Wenn die Funktion mit einer Art definiert ist, die umfasst einen Prototyp und entweder der Prototyp endet mit einem Auslassungszeichen (, ...) oder den Typen der Argumente, nachdem der Förderung mit den Arten des nicht kompatibel ist Parameter, das Verhalten ist nicht definiert.
  6.   
  7. Wenn die Funktion mit einem Typ definiert ist, dass enthält keinen Prototyp , und die Typen der Argumente nach dem Aufstieg ist nicht kompatibel mit denen des Parameter nach der Förderung, ist das Verhalten nicht definiert, es sei denn für die folgenden Fälle:      
        
    • one gefördert Typ ist ein vorzeichenbehaftete Ganzzahl-Typ, die andere beförderte Typ ist der entsprechende unsigned integer-Typ, und der Wert ist in beiden Typen darstellbarer;
    •   
    • beiden Typen sind Zeiger auf qualifizierte oder unqualifizierte Versionen eines Zeichentypen oder void.
    •   
  8.   

Ziffer 7

  
      
  1. Wenn der Ausdruck, der die genannte Funktion eine Art bezeichnet hat, die enthält einen Prototyp , werden die Argumente implizit konvertiert, wie durch Zuordnung zu den Typen der entsprechenden Parameter, die Art der Einnahme jeder Parameter die uneingeschränkte Version seines deklarierten Typ sein.
  2.   
  3. Die Notation Auslassungszeichen in einem Funktionsprototyp Deklarator Argument Typumwandlung führt nach dem letzten vereinbarten Parameter zu stoppen. Das Standardargument Aktionen sind auf Hinter Argumenten durchgeführt.
  4.   

Ziffer 8

  
      
  1. Keine andere Konvertierungen implizit durchgeführt wird; insbesondere sind die Anzahl und Arten von Argumenten nicht mit denen des Parameters in einer Funktionsdefinition verglichen, die enthält keinen Funktionsprototyp declarator .
  2.   

Was ich weiß

  • Die default Argument Aktionen sind char und short int / unsigned int und float double
  • Die optionalen Argumente variadische Funktionen (wie printf) unterliegen das Standardargument aktionen

Für das Protokoll, mein Verständnis einer Funktionsprototyp ist diese:

void func(int a, char b, float c);  // Function prototype
void func(int a, char b, float c) { /* ... */ }  // Function definition

Frage

Ich habe eine wirklich harte Zeit all dies groking. Hier sind einige Fragen, die ich habe:

  • Sie prototypisiert und nicht-prototypisiert Funktionen Verhalten wirklich unterscheidet sie so sehr, wie hinsichtlich Aktionen und implizite Konvertierung in Standard?
  • Wenn Sie Standardargument Aktionen auftreten? Ist es immer? Oder ist es nur in besonderen Fällen (wie bei variadische Funktionen)? Ist es davon ab, ob eine Funktion prototypisiert ist?
War es hilfreich?

Lösung

upvoted AProgrammer Antwort, das sind die realen Waren.

Für diejenigen von euch, die sich fragen, Warum sind die Dinge auf diese Weise: in den dunklen Zeiten vor 1988, war es nicht so etwas wie ein Funktionsprototyp in klassischen „K & R“ C, und die Standard-Argument Promotions wurden eingeleitet, weil (a) es im wesentlichen „frei“ waren, da es nicht mehr kostet ein Byte in einem Register zu setzen als ein Wort in einem Register zu setzen, und (b) auf mögliche Fehler in Parameterübergabe zu reduzieren. Der zweite Grund schnitt nie so recht, weshalb die Einführung von Funktionsprototypen in ANSI C die wichtigste Änderung jemals in der C-Sprache war.

Was, wenn Standard-Aktionen treten in: Standardargument Aktionen werden verwendet, genau dann, wenn der erwartete Typ des Arguments unbekannt , , das heißt, wenn es kein Prototyp ist oder wenn das Argument variadische.

Andere Tipps

  • (Non variadische) Parameter auf Funktionen mit einem Prototyp zu dem entsprechenden Typ umgewandelt werden, die char, kurz sein können, float.

  • Parameter zu Funktionen ohne Prototyp und variadische Parameter unterliegen Argument Aktionen auf Standard.

Wenn Sie eine Funktion mit einem Prototyp definieren und ohne den Prototyp oder umgekehrt verwenden und es hat Parameter vom Typ char, short oder float, werden Sie wahrscheinlich ein Problem während der Laufzeit haben. Sie werden die gleiche Art von Problemen mit variadische Funktionen haben, wenn die geförderte Typ paßt nicht, was verwendet wird, wenn die Argumentliste zu lesen.

. Beispiel 1: Problem, wenn eine Funktion mit einem Prototyp definiert, und deren Verwendung ohne

definition.c

void f(char c)
{
   printf("%c", c);
}

use.c

void f();

int main()
{
   f('x');
}

kann fehlschlagen, weil ein int übergeben werden und die Funktion ein Zeichen erwartet.

. Beispiel 2: Problem, wenn eine Funktion ohne Prototyp definiert, und mit einem mit

definition.c

void f(c)
   char c;
{
   printf("%c", c);
}

(Dies ist eine Art Definition ist sehr altmodisch)

use.c

void f(char c);

int main()
{
   f('x');
}

kann fehlschlagen, weil ein int erwartet, aber ein Zeichen wird übergeben werden.

Hinweis: Sie werden bemerken, dass alle Funktionen der Standardbibliothek Typen haben, die von Standardaktionen zur Folge haben. So dass sie nicht die Ursache für Probleme beim Übergang als Prototypen wurden hinzugefügt.

Ihre Verwirrung ergibt sich aus einem sehr leichten Missverständnis der Terminologie - beide Erklärungen und Definitionen können Prototypen sind (oder nicht):

void func(int a, char b, float c);

Das ist eine Funktion Erklärung , die einen Prototyp enthält.

void func(int a, char b, float c) { /* ... */ }

Das ist eine Funktion Definition , die einen Prototyp enthält.

„Prototyp-“ und „Nicht-Prototypen“ sind nur Attribute einer Funktion type , und beide Erklärungen und Definitionen einzuführen, um die Art der Funktion.

So haben Sie eine Erklärung ohne Prototyp haben:

void func();

oder Sie können eine Definition ohne Prototyp (K & R C-Stil) haben:

void func(a, b, c)
    int a;
    char b;
    float c;
{ /* ... */ }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top