2015-03-17 12 views
5

C99 hat static in einem Funktionsparameter (nur sinnvoll in der Funktionsdefinition, keine Deklaration) hinzugefügt:Warum wird [statisches N] zur Kompilierzeit nicht erzwungen?

void func(int a[static 10]) 
{ 
    if (a == NULL) 
     { /* this branch can be optimized out */ } 

    printf("%d", a[-1]); /* causes UB */ 
} 

jedoch seine Bedeutung in C11 6.7.6.3/7 als semantischen, keine definiert ist, Einschränkung, was bedeutet, dass der Compiler keine Diagnose ausgeben sollte, wenn die Funktion falsch aufgerufen wird. In der Tat muss der Compiler nicht abbrechen Kompilierung, es sei denn, es kann beweisen, dass UB in allen Zweigen verursacht wird. Zum Beispiel:

int main() 
{ 
    func(NULL); // UB 

    int b[9]; 
    func(b);  // UB 
} 

Warum hat die Norm dies keine Einschränkung machen (also eine Diagnose erforderlich ist)?

Sekundäre Frage: Warum wird static im Prototyp ignoriert (6.7.6.3/13), anstatt Teil der Funktionssignatur zu sein? Es scheint irreführend, dem Prototyp zu erlauben, es zu enthalten, aber der Funktionskörper nicht, und umgekehrt.

+1

'int * p = create_array(); func (p); Wie diagnostizierst du das? –

+2

Wie bei q2 ist das 'static' im Array-Deklarator kein Speicherklassen-Spezifizierer, daher gilt 6.7.6.3/13 nicht. Vgl. 6.7.6.3/2 - "Der einzige Speicherklassenbezeichner, der in einer Parameterdeklaration vorkommen soll, ist 'register'." –

+0

@TC re. q2: OK, heißt das, dass es im Prototyp tatsächlich signifikant ist? –

Antwort

5

Weil Verletzungen in allen Fällen nicht zur Kompilierzeit entdeckt werden können.

Zum Beispiel könnte das Argument ein Zeiger auf das Anfangselement eines mit malloc() zugewiesenen Arrays sein. Der Compiler kann im Allgemeinen nicht bestimmen, wie groß das Array ist. Auch wenn das Argument ein Zeigerobjekt ist, kann der Compiler im Allgemeinen erkennen, ob es null ist.

Der Hauptzweck dieser Funktion besteht nicht darin, Einschränkungen für Aufrufe zu erzwingen, sondern Optimierungen zu aktivieren. Der Compiler kann annehmen, dass der Parameter auf das Anfangselement eines Arrays der angegebenen Länge zeigt. In einigen Fällen kann dies eine bessere Codegenerierung ermöglichen.

Aber Compiler sicherlich können nicht-fatale Warnungen für die Fälle, die sie erkennen können. Der Standard besagt nicht, dass solche Warnungen nicht ausgegeben werden sollten.

+0

Gerade entdeckt, dass Clam 4.1 [tut Ausgabe Warnungen] (http://hamberg.no/erlend/posts/2013-02-18-static-array-indices.html) für einige einfache Fälle –

Verwandte Themen