Effet de bord (informatique)
En informatique, une fonction est dite à effet de bord (traduction mot à mot de l'anglais side effect, dont le sens est plus proche d'effet secondaire) si elle modifie un état en dehors de son environnement local, c'est-à -dire a une interaction observable avec le monde extérieur autre que retourner une valeur. Par exemple, les fonctions qui modifient une variable locale statique, une variable non locale ou un argument mutable passé par référence, les fonctions qui effectuent des opérations d'entrées-sorties ou les fonctions appelant d'autres fonctions à effet de bord[1]. Souvent, ces effets compliquent la lisibilité du comportement des programmes et/ou nuisent à la réutilisabilité des fonctions et procédures. Un langage comme Haskell les restreint délibérément dans des composants nommés monades.
Plus communément, un effet de bord apparaßt la plupart du temps lorsqu'une modification d'un programme cohérent (valeurs et états pris conformes aux spécifications) aboutit à des valeurs ou des comportements non prévus, à cause de la non prise en compte de la portée, de l'ensemble de définition de variables, ou du contrat des fonctions.
Langages
La programmation impérative permet l'emploi des effets de bord dans le fonctionnement de ses programmes, voire l'utilise délibérément (par exemple la déclaration COMMON
en FORTRAN) en permettant au compilateur d'en tenir compte (mot-clé volatile
en C).
La spécification du langage Fortran interdisait qu'une fonction modifie ses paramÚtres d'appel, et la plupart des compilateurs y veillaient.
La programmation fonctionnelle cherche au contraire à les minimiser et les isole souvent pour cela dans des structures prévues entre autres pour cela : les monades.
Matériel
Dans la conception des processeurs, des instructions peuvent modifier l'Ă©tat interne du processeur sans le dĂ©clarer explicitement. Ainsi une instruction d'addition peut ou non modifier des variables de conditions (retenue, zĂ©ro, dĂ©bordementâŠ). Cela pose un problĂšme de conception si le processeur comporte un pipeline d'instructions. Ainsi, le 360/91 d'IBM, muni de quatre unitĂ©s arithmĂ©tiques et logiques travaillant simultanĂ©ment, rapportait parfois une IMPRECISE INTERRUPT (dĂ©routement mal localisĂ©) « dans les parages » d'une certaine adresse, sans pouvoir prĂ©ciser davantage laquelle.
On peut éviter ces aléas en limitant le jeu d'instructions à des instructions sans effet de bord. Dans le pire des cas, des circuits additionnels détectent les effets de bord et invalident le pipeline si l'instruction suivante dans celui-ci dépend des valeurs affectées. Le calcul est donc simplement un peu retardé.
Opérateurs à effet de bord
Par extension[2], on dit d'un opérateur qu'il a un effet de bord lorsqu'il modifie la valeur de l'un de ses opérandes.
La valeur rĂ©sultant de l'opĂ©ration peut ĂȘtre utilisĂ©e (stockĂ©e dans une variable ou transmise en paramĂštre d'une fonction, par exemple), mais de tels opĂ©rateurs sont souvent employĂ©s uniquement pour leur effet de bord. L'expression, comportant une opĂ©ration dont le rĂ©sultat est ignorĂ©, devient alors une instruction.
Exemples en C++ :
++x; // ++ incrémente x
c = b += a; // le résultat de += est stocké dans c mais celui de = est ignoré
L'opérateur d'affectation =
est souvent employé par erreur à la place de l'opérateur d'égalité ==
. Son effet de bord est de modifier son 1er opérande en lui affectant la valeur de son 2e opérande. Son résultat est la valeur qui a été affectée.
if (x = 0) { // x est modifiée et devient 0
std::cout << "nul"; // "nul" n'est jamais affichée car x = 0 renvoie toujours 0
}
Transparence référentielle
Ne pas avoir d'effet de bord est une condition nĂ©cessaire mais non suffisante pour la transparence rĂ©fĂ©rentielle. La transparence rĂ©fĂ©rentielle signifie qu'une expression (telle qu'un appel de fonction) peut ĂȘtre remplacĂ©e par sa valeur sans affecter le comportement du programme. L'expression doit pour cela ĂȘtre pure, c'est-Ă -dire avoir la mĂȘme valeur pour les mĂȘmes entrĂ©es et son Ă©valuation ne doit pas avoir d'effets de bord. Une fonction sans effets de bord peut retourner des valeurs diffĂ©rentes selon son histoire ou son environnement externe, par exemple si sa sortie dĂ©pend de la valeur d'une variable locale statique ou d'une variable non locale respectivement.
Exemple d'un programme utilisant un effet de bord en C++
#include <iostream>
int x = 0;
void f() {
x = 1;
}
int main() {
std::cout << x << std::endl;
f();
std::cout << x << std::endl;
return 0;
}
Ce programme imprime sur la sortie standard :
0 1
L'effet de bord de la fonction f
est de modifier la valeur de la variable globale x
.
Notes et références
- (en) David A. Spuler et A. Sayed Muhammed Sajeev, « Compiler Detection of Function Call Side Effects », sur CiteSeerX, (consulté le ) : « The term Side effect refers to the modification of the nonlocal environment. Generally this happens when a function (or a procedure) modifies a global variable or arguments passed by reference parameters. But here are other ways in which the nonlocal environment can be modified. We consider the following causes of side effects through a function call: 1. Performing I/O. 2. Modifying global variables. 3. Modifying local permanent variables (like static variables in C). 4. Modifying an argument passed by reference. 5. Modifying a local variable, either automatic or static, of a function higher up in the function call sequence (usually via a pointer). »
- Les opĂ©rateurs pouvant ĂȘtre considĂ©rĂ©s comme des fonctions