3

J'ai remarqué une utilisation intensive du mot clé restrict dans l'un de nos anciens projets.
Je comprends la logique de restrict, mais je doute de son utilité lorsqu'elle est appliquée à certaines de ces fonctions.Le mot-clé restrict n'a-t-il aucun sens sur les paramètres des types de pointeurs uniques?

Prenez les deux exemples suivants:

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); 
} 

Y at-il une raison valable on pourrait marquer les paramètres de funcA et funcB avec restrict?

funcA prend seulement 1 paramètre. Comment pourrait-il avoir la même adresse que toute autre chose?

funcB prend des paramètres de différents types. S'il s'agissait de la même adresse, cela ne viendrait-il pas à briser la stricte règle des alias?

+0

Si la fonction peut utiliser des pointeurs/objets globaux, je pense que 'restrict' a une valeur. – chux

+0

En ce qui concerne les pointeurs vers différents types, C a spécifié 'char * fgets (char * restreindre s, int n, FICHIER * restreindre le flux);' il semble que le comité standard voit la valeur avec 'restrict' à différents types. – chux

+0

Intéressant. Bien que le char ne soit pas un peu une exception car un char * est autorisé à pointer vers un autre type. –

Répondre

5

Le mot-clé restrict est une déclaration d'intention, pour une optimisation améliorée. Cela signifie que les objets pointés par les pointeurs donnés ne seront pas pointés par quoi que ce soit d'autre pour la durée de vie des paramètres de la fonction (dans ce cas).

Vous n'affichez pas le code des fonctions, il peut donc y avoir des variables statiques à l'intérieur. Restreindre est une garantie que ces variables statiques n'aliasent pas les paramètres.

Il peut y avoir des variables globales non affichées dans votre exemple. Restreindre est une garantie que ces variables globales n'aliasent pas les paramètres.

En réalité, vous avez raison: il est probable que quelqu'un est juste allé un peu fou avec restreindre. Mais restreindre pas signifie "ce paramètre et ce paramètre". Cela signifie "ce pointeur et tout autre pointeur".

+0

Bon point sur les variables statiques à l'intérieur. – chux

+0

Cela signifie qu'une des deux conditions s'appliquera pour la durée de vie du pointeur, à chaque objet accédé ou aux pointeurs dérivés: (1) l'objet ne sera pas modifié par aucun moyen (pendant la vie du pointeur), ou (2) l'objet ne sera pas accessible (y compris les lectures) par tout moyen autre que le pointeur ou d'autres dérivés de celui-ci. Un pointeur qualifié 'restrict' peut identifier un objet avec une durée statique ou automatique si les conditions ci-dessus sont respectées, mais ces objets ne peuvent pas être accédés" directement "pendant la durée du pointeur sauf s'ils ne sont pas modifiés pendant cette durée. – supercat

0

Compte tenu de la fonction:

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

un compilateur peut voir assez facilement - en raison de la qualification restrict - qu'il n'y a pas moyen légitime par lequel bar() peut accéder *p. Il peut ainsi optimiser le code ci-dessus dans:

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

et il peut effectuer une telle optimisation sans avoir à connaître quoi que ce soit au sujet whasoever bar(). En l'absence du qualificatif, le compilateur devrait tenir compte de la possibilité que l'appelant puisse avoir par ex. passé l'adresse d'un int global qui est modifié par bar(), mais à cause de restrict un compilateur n'aurait pas à s'inquiéter à ce sujet.