3

Ich habe eine starke Verwendung des Schlüsselwortes restrict in einem unserer älteren Projekte bemerkt.
Ich verstehe die Begründung für restrict, aber ich Frage seine Nützlichkeit, wenn auf einige dieser Funktionen angewendet.Ist das Schlüsselwort restrict bedeutungslos für Parameter eindeutiger Zeigertypen?

Nehmen Sie die folgenden zwei Beispiele:

void funcA(int *restrict i){ 
    // ... 
} 

void funcB(int *restrict i, float *restrict f){ 
    // ... 
} 

int main(){ 

    int i = 1; 
    float f = 3.14; 

    funcA(&i); 
    funcB(&i,&f); 
} 

Gibt es einen triftigen Grund könnte man die Parameter der funcA und funcB mit restrict Tag?

funcA benötigt nur 1 Parameter. Wie könnte es die gleiche Adresse wie alles andere haben?

funcB verwendet Parameter verschiedener Typen. Wenn sie die gleiche Adresse wären, würde das nicht schon die strenge Aliasing-Regel brechen?

+0

Wenn die Funktion globale Zeiger/Objekte verwenden kann, denke ich, dass 'restrict' einen Wert hat. – chux

+0

In Bezug auf Zeiger auf verschiedene Typen, C angegeben 'char * fgets (char * beschränken s, int n, FILE * Stream einschränken);' so scheint es das Standard-Komitee sieht Wert mit 'restrict' zu verschiedenen Typen. – chux

+0

Interessant. Obwohl char keine Ausnahme ist, kann char * auf einen anderen Typ verweisen. –

Antwort

5

Das Schlüsselwort restrict ist eine Absichtserklärung für eine verbesserte Optimierung. Das bedeutet, dass auf die Objekte, auf die die angegebenen Zeiger zeigen, nicht durch etwas anderes für die Lebensdauer der (in diesem Fall) Funktionsparameter hingewiesen wird.

Sie zeigen den Code der Funktionen nicht an, daher können statische Variablen darin enthalten sein. Restrict ist eine Garantie, dass diese statische Variable die Parameter nicht aliasiert.

Möglicherweise sind globale Variablen in Ihrem Beispiel nicht dargestellt. Restrict ist eine Garantie, dass diese globalen Variablen die Parameter nicht als Aliasnamen verwenden.

In der Realität haben Sie Recht: Es ist wahrscheinlich, dass jemand nur ein wenig verrückt mit schränkt wurde. Aber beschränken bedeutet nicht bedeuten "diesen Parameter und diesen Parameter". Es bedeutet "dieser Zeiger und irgendein anderes Zeiger".

+0

Guter Punkt über innere statische Variablen. – chux

+0

Dies bedeutet, dass eine von zwei Bedingungen für die Lebensdauer des Zeigers gilt, für jedes Objekt, auf das zugegriffen wird, oder für von ihm abgeleitete Zeiger: (1) das Objekt wird nicht modifiziert (während der Lebensdauer des Zeigers), oder 2) auf das Objekt wird nicht zugegriffen (einschließlich Lesevorgänge) mit anderen Mitteln als dem Zeiger oder anderen, die davon abgeleitet sind. Ein "restrict" -qualifizierter Zeiger kann ein Objekt mit statischer oder automatischer Dauer identifizieren, wenn die obigen Bedingungen gelten, aber auf solche Objekte kann während der Lebensdauer des Zeigers nicht "direkt" zugegriffen werden, es sei denn, sie werden während dieser Lebensdauer nicht modifiziert. – supercat

0

die Funktion Gegeben:

int foo(int *restrict p) 
{ 
    *p = 3; 
    bar(); 
    return *p; 
} 

ein Compiler ziemlich leicht sehen kann - wegen der restrict Qualifier -, dass es keine legitime Art und Weise ist, durch die bar()*p zugreifen können. Es kann somit den obigen Code in optimieren:

int foo(int *restrict p) 
{ 
    bar(); 
    *p = 3; 
    return 3; 
} 

und es kann eine solche Optimierung durchführen ohne etwas whasoever über bar() kennen. In Abwesenheit des Qualifikators müsste der Compiler die Möglichkeit berücksichtigen, dass der Anrufer z.B. übergab die Adresse eines globalen int, die von bar() geändert wird, aber wegen restrict würde ein Compiler darüber nicht sorgen müssen.

Verwandte Themen