Compilateurs

Dans la fonction ci-dessus, pourquoi le compilateur ne peut-il pas, en l'état, sortir de la boucle la lecture de *b ?

void add(int *a, int *b, int n) {
    for (int i = 0; i < n; i++)
        a[i] += *b;
}
  1. A*b étant un entier, le sortir de la boucle ferait perdre de la précision
  2. Ba et b peuvent désigner le même emplacement, et une écriture dans a[i] pourrait modifier *b
  3. CLe compilateur n'a aucunement le droit d'optimiser une fonction prenant des pointeurs en argument
Afficher la réponse et l'explication

Réponse : B. a et b peuvent désigner le même emplacement, et une écriture dans a[i] pourrait modifier *b

À première vue, *b ne change pas dans la boucle et une seule lecture suffirait. Mais si l'appelant passe un pointeur b désignant un élément de a, comme add(x, &x[3], n), l'écriture dans a[3] modifie *b. Ne pouvant exclure cette possibilité (alias), le compilateur génère du code qui relit la valeur à chaque fois. En C, qualifier les pointeurs de restrict, en garantissant qu'ils désignent des emplacements distincts, permet l'optimisation. Ce n'est ni un problème de précision ni une interdiction d'optimiser.

S'entraîner sur ce thème Retour au thème

Autres questions sur Compilateurs

  1. Pour l'allocation de registres par coloration du graphe d'interférence, quelle combinaison de ce que représentent nœuds et arêtes est correcte ?
  2. Lorsqu'un « déversement » (spill) se produit lors de l'allocation de registres, qu'advient-il du code généré ?
  3. Quel est le principal objectif de l'ordonnancement des instructions par le compilateur ?
  4. Quel effet produit l'optimisation des appels terminaux appliquée au dernier appel récursif de la fonction ci-dessus ?
  5. Quelle différence entre compilateur et interpréteur est correcte ?

Comparatifs sur ce thème