2016-03-23 6 views
0

The example hinzufügen genommen wird:A verwirrendes Beispiel über das C Stichwort "restrict"

void updatePtrs(size_t *restrict ptrA, size_t *restrict ptrB, size_t *restrict val) 
{ 
    *ptrA += *val; 
    *ptrB += *val; 
} 

I diese Funktion in den main() nennen:

int main(void) 
{ 
    size_t i = 10; 
    size_t j = 0; 

    updatePtrs(&i, &j, &i); 

    printf("i = %lu\n", i); 
    printf("j = %lu\n", j); 

    return 0; 
} 

Der val Zeiger nicht zweimal geladen wird gemäß nach der Wikipedia-Beschreibung, so sollte der Wert von j 10 sein, aber es ist 20 tatsächlich.

Ist mein Verständnis über dieses Schlüsselwort nicht korrekt? Sollte ich einige spezifische Optionen von gcc verwenden?

Vielen Dank im Voraus.

Antwort

5

Ihr Code verursacht undefiniertes Verhalten. restrict ist eine Zusage von Ihnen an den Compiler, dass alle Zeigerparameter auf unterschiedliche Speicherbereiche zeigen.

Sie brechen dieses Versprechen, indem Sie &i für zwei der Argumente setzen.

(In der Tat, mit restrict ist es erlaubt, überlappende Zeiger zu übergeben, aber nur, wenn keine Schreibvorgänge durch einen der überlappenden Zeiger innerhalb der Funktion erfolgt sind. Aber normalerweise würden Sie sich nicht mit restrict kümmern, wenn es kein Schreiben gibt) .


FWIW, auf meinem System mit gcc 4.9.2, ausgegeben j = 20 bei -O0 und j = 10 bei -O1 oder höher, was darauf schließen lässt, dass der Compiler tatsächlich Kenntnis von dem restrict nehmen wird. Da es sich um ein undefiniertes Verhalten handelt, können Ihre Ergebnisse natürlich variieren.

+0

Ich möchte nur dieses Schlüsselwort verstehen, also brich ich das Versprechen. es wird 10, wenn "-O1" für gcc (5.2.1) verwendet wird. – Choes