Lordre dans lequel les paramètres dune fonction sont évalués nest 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++, cest la deuxième solution qui est choisie, aussi étrange que cela puisse paraître. En tout état de cause, un tel code nest 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 sagit en fait de deux appels de fonction dissimulés (voir chapitre 7) :
operator<<( operator<<(cout, --i), --i);
et lordre dévaluation est alors différent comme on vient de le dire.
Même sil ny a quun 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 à lappel de f(5, 5)
en Turbo C++, mais peut valoir f(6, 5)
avec dautres 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 | Sommaire | Suivant |