Skutek uboczny (informatyka)
Skutek uboczny, efekt uboczny (ang. side effect) – dowolny efekt wyrażenia lub wywołania funkcji, który wykracza poza zwrócenie wartości, np. interakcja z systemem operacyjnym lub zmiana wartości zmiennej globalnej. Innymi słowy skutek uboczny następuje, gdy modyfikowany zostaje jakiś stan programu poza swoim lokalnym środowiskiem, to znaczy następuje zauważalna interakcja ze „światem zewnętrznym”, oprócz zwracania wartości.
Pomimo nazwy (nieco mylącej) wiele funkcji jest wywoływanych właśnie w celu uzyskania skutku ubocznego.
Np. wyrażenie 2 + 3 nie ma skutków ubocznych, natomiast wyrażenie a = 2 + 3 ma oczywisty skutek uboczny na zmiennej nielokalnej a – modyfikuje jej wartość. Innym przykładem skutku ubocznego jest poniższa funkcja w Perlu:
sub add() {
my $val = 0;
$count++;
$val += $_ foreach (@_);
return $val;
}
Jej zasadniczym celem jest zwrócenie sumy wartości podanych argumentów, ale efektem ubocznym jest wyłącznie zwiększenie wartość pewnej zmiennej globalnej $count.
Charakterystyka
Z formalnego punktu widzenia większość funkcji w językach wysokiego poziomu powoduje efekty uboczne (w postaci komunikacji z systemem operacyjnym), np. funkcje z rodziny printf() w języku C zwracają liczbę „wydrukowanych” znaków, a sama operacja „wydrukowania” tych znaków jest właśnie efektem ubocznym.
W programach napisanych w językach niskopoziomowych ogromna większość instrukcji powoduje skutki uboczne – w asemblerze istnieją praktycznie wyłącznie skutki uboczne i nie ma żadnego innego mechanizmu realizacji obliczeń. W asemblerze istnieją nawet tzw. ukryte skutki uboczne, do których zalicza się niejawne modyfikowanie flag rejestru stanu procesora, np. w czasie wykonywania rozkazu procesora, który jawnie modyfikuje zawartość rejestrów procesora.
Natomiast w programach napisanych w językach funkcyjnych skutków ubocznych jest niewiele i tylko tam gdzie są one rzeczywiście niezbędne, np. w operacjach wejścia/wyjścia.
Istnienie skutków ubocznych znacznie utrudnia przeprowadzanie wielu rodzajów optymalizacji kodu wynikowego; mogą one powodować trudne do zdiagnozowania błędy w działaniu aplikacji, szczególnie jeżeli programista nie jest świadomy istnienia efektów ubocznych używanych funkcji.