Effet de bord (informatique)

Un article de Wikipédia, l'encyclopédie libre.
Sauter à la navigation Sauter à la recherche
Page d'aide sur l'homonymie Pour les articles homonymes, voir Effet de bord.

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 observable interne ou externe. Par exemple, les fonctions qui modifient une variable locale statique (état interne), globale (état externe) ou un ou plusieurs de ses arguments, les fonctions qui lèvent une exception, les fonctions qui écrivent des données vers un écran ou un fichier, les fonctions qui lisent les données d'un clavier ou d'un fichier, les fonctions appelant d'autres fonctions à effet de bord. 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[modifier | modifier le code]

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[modifier | modifier le code]

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[modifier | modifier le code]

Par extension[1], 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[modifier | modifier le code]

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 sans état, c'est-à-dire être pure (ne pas avoir d'effets de bord) et déterministe (donner toujours la même valeur pour les mêmes entrées). Une fonction sans effets de bord peut retourner des valeurs différentes selon son histoire ou son environnement, par exemple si sa sortie dépend de la valeur d'une variable locale statique ou d'une variable globale respectivement.

Exemple d'un programme utilisant un effet de bord en C++[modifier | modifier le code]

#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[modifier | modifier le code]

  1. les opérateurs pouvant être considérés comme des fonctions

Voir aussi[modifier | modifier le code]