Het sleutelwoord restrict is een specificator voor pointers, geïntroduceerd in de C99-standaard. Het geeft de compiler aan dat de pointer de enige manier is om toegang te krijgen tot een geheugenobject binnen het bereik van de pointer. Dit helpt de optimizer aanzienlijk bij het genereren van efficiëntere machinecode, vooral bij het werken met grote buffers.
Bijvoorbeeld:
void vector_add(int * restrict a, int * restrict b, int * restrict c, size_t n) { for (size_t i = 0; i < n; ++i) c[i] = a[i] + b[i]; }
Hier wordt verondersteld dat de arrays a, b en c niet overlappen. Het schenden van deze eis leidt tot ongedefinieerd gedrag en moeilijk opspoorbare fouten.
Het gebruik van restrict wordt alleen aanbevolen als je zeker weet dat geen andere pointers of bijwerkingen naar hetzelfde geheugen verwijzen.
Kan dezelfde geheugenwaarde tegelijkertijd zichtbaar zijn via twee restrict-pointers?
Antwoord:
Nee, dit zal leiden tot ongedefinieerd gedrag. Er is geen garantie dat de compiler de wijzigingen die via de tweede pointer zijn aangebracht, zal inzien. Voorbeeld van kritiek onjuiste code:
void f(int * restrict x, int * restrict y) { x[0] = 1; y[0] = 2; } int main() { int v; f(&v, &v); // Schending van de restrict-voorwaarde }
Verhaal
In de financiële rekencore werden functies geoptimaliseerd voor arrays met toevoeging van restrict, maar men veronachtzaamde dat arrays konden overlappen volgens een deel van de business logica. Dit leidde tot een onjuiste balansberekening bij verkeerd gebruik.
Verhaal
De batchmatrixvermenigvuldiging versnelde na toepassing van restrict, maar in een van de iteraties kwam de resultaatarray in conflict met een van de inputarrays — het resultaat werd onvoorspelbaar en de bug werd alleen gedetecteerd tijdens belastingstest.
Verhaal
In een van de image processing-functies werden twee pointers naar stukken van dezelfde buffer per ongeluk gedeclareerd met restrict. Na de update van de compiler en zijn optimizer werd het resultaat van de beeldverwerking abrupt vervormd — oorzaak: de compiler begon actief de cache opnieuw te gebruiken en negeerde de aanpassingen.