Restrânge

Versiunea actuală a paginii nu a fost încă examinată de colaboratori experimentați și poate diferi semnificativ de versiunea revizuită pe 22 martie 2021; verificările necesită 22 de modificări .

restrict  este un cuvânt cheie în limbajul de programare C introdus de standardul C99 și utilizat în declarațiile pointerului .

char * restrictioneaza p1 ; int ** restrictioneaza p2 ; float * restrânge p3 , * restrânge p4 ;

Cuvântul cheie restrictpermite programatorului să spună compilatorului că pointerul care este declarat se adresează unei regiuni de memorie care nu este referită de niciun alt pointer. Garanția că mai mult de un pointer nu se va referi la o zonă de memorie este dată de programator. În acest caz, compilatorul de optimizare poate genera cod mai eficient (vezi un exemplu de mai jos).

Utilizarea cuvântului cheie restrictla declararea altor obiecte decât pointerii nu este definită de standard.

Folosind cuvântul cheie, restrictun program scris în „inteligent” C poate fi la fel de rapid ca un program scris în „prost” Fortran [1] .

Nu există niciun cuvânt cheie în limbajul C++restrict (nu este descris în standard), dar dezvoltatorii diferitelor compilatoare C++ au adăugat cuvinte cheie care sunt similare ca scop, de exemplu:

Exemplu de optimizare

Compilatorul poate genera mai puțin cod dacă știe că un singur pointer se adresează unui bloc de memorie. Luați în considerare un exemplu. Este definită următoarea funcție:

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

Pointers ptrAși ptrBse valpot referi la același bloc de memorie.

Pentru această funcție, compilatorul va genera ceva de genul următor cod:

sarcina R1 * val ; citiți valoarea din memorie la pointer val sarcina R2 * ptrA ; citiți valoarea din memorie la pointerul ptrA adăugați R2 += R1 ; efectuați setul de adunare R2 * ptrA ; scrieți rezultatul în memorie la pointerul ptrA ; similar pentru sarcina ptrB R1 * val ; citind de val a doua oară încărcare R2 * ptrB adăugați R2 += R1 set R2 * ptrB

Rețineți că valoarea indicatorului este valcitită din memorie de două ori. Acest lucru se datorează faptului că pointerul ptrAse poate referi la același bloc de memorie ca și val, ceea ce înseamnă că valoarea valse poate schimba atunci când valoarea este scrisă în pointer ptrA.

Când se utilizează cuvântul cheie restrict, definiția funcției ar fi:

void updatePtrs ( size_t * restricționează ptrA , size_t * restricționează ptrB , size_t * restricționează valoarea ) { * ptrA += * val ; * ptrB += * val ; }

Cuvântul cheie restrictîi spune compilatorului că ptrApointerii ptrBși valnu se adresează niciodată aceluiași bloc de memorie. Acest lucru este garantat de programator.

În acest caz, compilatorul va genera ceva de genul următor cod:

sarcină R1 * val încărcare R2 * ptrA adăugați R2 += R1 set R2 * ptrA ; sarcina R1 ← *val ; dispărut încărcare R2 * ptrB adăugați R2 += R1 set R2 * ptrB

Rețineți că codul a devenit mai scurt datorită faptului că valoarea valeste citită din memorie o singură dată.

Exemple de comportament nedefinit

Un pointer cu un calificator de tip restrictcătre un pointer cu un calificator de tip restrictpoate fi definit doar într-un bloc imbricat. Exemplu:

struct T { int i ; }; struct T var_1 ; int main () { struct T * restriction var_2 = & var_1 ; int * restricționează var_3 = & var_2 -> i ; // comportament nedefinit { int * restricționează var_4 = & var_2 -> i ; // valid } returnează 0 ; }

Definirea unui pointer var_3 este un comportament nedefinit deoarece se var_3află în același bloc cu var_2. Definiția var_4este într-un bloc imbricat și este validă.

__restrict pentru metode în C++

Cuvântul cheie pentru o __restrictmetodă de structură sau clasă C++ indică faptul că pointerul este de tipul " ". Exemplu: thisT * __restrict const

struct T { metoda void () __restrict {} };

Literatură

Vezi și

Note

  1. Ulrich Drepper . Memorie. Partea 5 . Ce ar trebui să știe fiecare programator despre memorie . Revista electronică lwn.net (23 octombrie 2007). - Fără cuvântul cheie, compilatorul consideră că pointerii pot indica același bloc de memorie și generează cod non-optim. Acesta este unul dintre motivele pentru care Fortran este încă folosit pentru calcule numerice (făcând mai ușor scrierea codului rapid). Teoretic, introducerea lui C99 ar trebui să rezolve această problemă. Consultat la 5 decembrie 2014. Arhivat din original la 30 martie 2015.restrictrestrict
  2. gnu.org Restricţionarea aliasului pointerului Arhivat 6 august 2016 la Wayback Machine  . documentație gcc .