If debugging is the process of removing bugs, then programming must be the process of putting them in. ~Author Unknown

My software never has bugs. It works *exactly* as I wrote it! ~ Author Unknown

Dzisiejsza historia oparta jest, w większości, na faktach. Ukryliśmy tylko imię naszego programisty.

Był sobie Tomek programista. Tomek miał do napisania w C# fragment większego algorytmu. Jako, że kod był dobrze podzielony mogło to zrobić wiele osób. Jedną z rzeczy które miały być w tym fragmencie było stworzenie wektora z dwóch elementów:

[1 Math.Pow(Math.Sqrt(2), -BassCorrectRaw)-1]

Tomek nie był pozostawiony sam sobie. Miał API, które było dość rozbudowane.
Był dostępny typ VectorDouble jak poniżej:

public class VectorDouble : Vector<double>, IVectorDoubleReadOnly

{                       

    public VectorDouble() : base()

    { }

 

    public VectorDouble(int size) : base(size)

    { }

 

    public VectorDouble(int size, double value) : base(size, value) 

    { }

 

    public VectorDouble(params double[] vector) : base(vector)

    { }       

   //…

}

Wystarczyło go użyć i zainicjować wartościami co też nasz bohater uczynił. Napisał taki oto kod:

IVectorDoubleReadOnly BassCorrectCoefA = new VectorDouble(1, Math.Pow(Math.Sqrt(2), -BassCorrectRaw) – 1);

Widzicie już problem Tomcia? Jeśli chcecie pomyśleć sami to nie klikajcie na poniższy link. Jak już się zdecydujecie to zapraszam do dalszego czytania.

Pokaż rozwiązanie

Problemem Tomcia są dwa szczególne konstruktory w klasie VectorDouble. Tomek chciał wywołać konstruktor przyjmujący params double[] vector natomiast ponieważ użył wartości “1”, wykonał się nie ten konstruktor, który zamierzał. Tomek ma review kodu, ma w firmie Unit testy a jednak ten błąd przemknął się i przez dość długi czas pozostawał niewykryty powodując błędne kalkulacje. A rozwiązanie jest banalne:

IVectorDoubleReadOnly BassCorrectCoefA = new VectorDouble(1d, Math.Pow(Math.Sqrt(2), -BassCorrectRaw) – 1);

Tak. Dobrze widzicie. Poprawne i niepoprawne użycie różni się tylko literką “d”. Łatwo to przegapić.

Pytanie czy to nieznajomość Tomka spowodowała błąd czy jednak API nie jest na tyle przejrzyste, aby takim sytuacjom zapobiegać? Jak uważacie?