Ordre d’évaluation des paramètres

L’ordre dans lequel les paramètres d’une fonction sont évalués n’est pas précisé par le langage. Il en résulte que les passages avec deux effets de bord sur la même variable ont des résultats indéterminés. Par exemple, l’écriture suivante :

int i = 10;
f(i++, i++)        // effet ?

appellera soit f(10, 11), soit f(11, 10) suivant le compilateur. En Turbo C++, c’est la deuxième solution qui est choisie, aussi étrange que cela puisse paraître. En tout état de cause, un tel code n’est absolument pas portable, il doit être évité.

Signalons que le problème est particulièrement grave avec les opérateurs. Par exemple, l’écriture :

int i = 6;
int j = --i << --i;

placera en Turbo C++ la valeur 80 (5 << 4) dans j et non la valeur 128 (4 << 5). Par contre, l’écriture :

cout << --i << --i;

fera écrire les chiffres 4 puis 5 au contraire, car il s’agit en fait de deux appels de fonction dissimulés (voir chapitre 7) :

operator<<( operator<<(cout,  --i), --i);

et l’ordre d’évaluation est alors différent comme on vient de le dire.

Même s’il n’y a qu’un seul effet de bord, mais que la variable est réutilisée, il y a ambiguïté. Par exemple, l’écriture :

int i = 6;
f(i, --i);

équivaut à l’appel de f(5, 5) en Turbo C++, mais peut valoir f(6, 5) avec d’autres compilateurs. Par contre, l’écriture :

j = i << --i;

place la valeur 160 (5 << 5) dans j, et non 192 (6 << 5), car les effets de bord des expressions sont calculés en premier par Turbo C++. De même, l’écriture :

cout << i << --i;

envoie les caractères 5 et 5 à l’écran. Toutes ces écritures sont non portables et aventureuses.

Retenir cette règle : éviter absolument tout appel de fonction et toute expression contenant un effet de bord sur une variable et une autre utilisation quelconque de cette même variable.

Précédent Précédent Sommaire Sommaire Suivant Suivant