Was ist der Zweck des statischen Schlüsselworts im Array-Parameter einer Funktion wie "char s [static 10]"?


144

Beim Durchsuchen eines Quellcodes bin ich auf eine Funktion wie diese gestoßen:

void someFunction(char someArray[static 100])
{
    // do something cool here
}

Bei einigen Experimenten scheinen dort auch andere Qualifikanten zu erscheinen:

void someFunction(char someArray[const])
{
    // do something cool here
}

Es scheint, dass Qualifizierer nur innerhalb von zulässig sind, [ ]wenn das Array als Parameter einer Funktion deklariert ist. Was machen diese? Warum ist es bei Funktionsparametern anders?

Antworten:


127

Die erste Erklärung weist den Compiler an, die someArrayist mindestens 100 Elemente lang. Dies kann für Optimierungen verwendet werden. Zum Beispiel bedeutet es auch, dass dies someArrayniemals der Fall ist NULL.

Beachten Sie, dass der C-Standard vom Compiler keine Diagnose verlangt, wenn ein Aufruf der Funktion diese Anforderungen nicht erfüllt (dh es handelt sich um ein stilles undefiniertes Verhalten).

Die zweite Deklaration deklariert einfach someArray(nicht someArraydie Elemente!) Als const, dh Sie können nicht schreiben someArray=someOtherArray. Es ist dasselbe, als ob der Parameter wäre char * const someArray.

Diese Syntax kann nur im Innersten verwendet werden [] eines Array-Deklarators in einer Funktionsparameterliste verwendet werden. In anderen Zusammenhängen wäre dies nicht sinnvoll.

Der Standardtext, der beide oben genannten Fälle abdeckt, befindet sich in C11 6.7.6.3/7 (war 6.7.5.3/7 in C99):

Eine Deklaration eines Parameters als '' Array vom Typ '' wird an '' qualifizierter Zeiger auf Typ '' angepasst, wobei die Typqualifizierer (falls vorhanden) diejenigen sind, die in der [und ]der Array-Typableitung angegeben sind. Wenn das Schlüsselwort static auch innerhalb der Ableitung [und ]des Array-Typs erscheint , muss der Wert des entsprechenden tatsächlichen Arguments für jeden Aufruf der Funktion den Zugriff auf das erste Element eines Arrays mit mindestens so vielen Elementen ermöglichen, wie durch das angegeben Größenausdruck.


35
Zu diesem Thema: Ich frage mich, ob es vorzuziehen ist, int foo(struct bar [static 1]);statt int foo(struct bar *);als Signatur für Funktionen zu verwenden, die keine NULL-Zeiger akzeptieren. (Ich weiß, dass gcc eine alternative, nicht standardmäßige Syntax hat, um solche Funktionen zu
kennzeichnen

2
Ich habe gerade gcc und clang überprüft und gehe auch nicht davon aus, dass someArray immer nicht null ist, wenn ich sie auffordere, mit 0 zu vergleichen. Außerdem habe ich Schwierigkeiten, die genaue Klausel in C99 zu finden, die sie definiert. In 6.7.5.3-21 gibt es einen Hinweis, der die beabsichtigte Bedeutung erwähnt und das war's. Ich bezweifle, dass wir uns darauf verlassen können. Darüber hinaus ist all dies nicht Teil der Funktionssignatur, sodass wir nicht viel durchsetzen.
Nordic Mainframe

5
Dieser Link scheint verrottet zu sein. Ist es das, worauf er hinwies? pic.dhe.ibm.com/infocenter/zos/v1r12/…
Ross Aiken

13
@NordicMainframe: Es ist einige Zeit her, aber die aktuelle Version von clangjetzt warnt korrekt, wenn Sie versuchen, ein bekanntes NULL-Argument an eine Funktion mit einer [static 1]Parameterdeklaration zu übergeben.
Dreamlax

1
@CiroSantilli removed 文件 六四 事件 法轮功if (!someArray) { somecode... }könnte entfernt werden
MM
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.