Posts from 2008

Funkcje zagnieżdżone i C++

2008-12-30 20:19

Niekiedy przydatna okazuje się możliwość definiowania funkcji widocznych wyłącznie w obrębie innej funkcji – czyli procedur zagnieżdżonych. Używa się tego najczęściej do krótkich, pomocniczych funkcji; oto najprostszy przykład w języku, który to umożliwia (Delphi):
[delphi]// oblicza odległość między dwoma punktami
function Distance(p1, p2 : TPoint) : Double;
function Square(X : Double) : Double;
begin
Result := X * X;
end;
begin
Result := Sqrt(Square(p1.X – p2.X) + Square(p1.Y – p2.Y));
end;[/delphi]
Takim językiem nie jest jednak C++, więc pewnie istnieje ku temu jakiś bardzo ważny powód… Bo czyż nie jest tak z każdą przydatną funkcjonalnością, która została w nim pominięta? ;D
Ale żarty na bok. W C++ można – przy odrobinie pomysłowości – osiągnąć dość podobny efekt:

  1. double Distance(POINT p1, POINT p2)
  2. {
  3.     static class
  4.     {
  5.         public:
  6.             double operator() (double x) const { return x * x; }
  7.     } Square;
  8.  
  9.     return sqrt(Square(p1.X - p2.X) + Square(p1.Y - p2.Y));
  10. }

Nie tworzymy tutaj funkcji, tylko odpowiednio nazwany obiekt anonimowej klasy, któremu przeciążamy operator nawiasów (wywołania funkcji). Efekt na oko jest taki sam: mamy pewną nazwę (Square), którą możemy użyć jak funkcję, lecz nie jest ona widoczna poza macierzystą procedurą (czyli Distance). Nasz obiekt deklarujemy też jako statyczny, dzięki koszt jego tworzenia i niszczenia ponosimy tylko raz, a ponadto nie zajmuje on miejsca na stosie (gdyż w innym przypadku z pewnością zająłby je; standard C++ mówi, że nawet obiekty klas bez zadeklarowanych pól nie mają rozmiaru 0).

Ta sztuczka jest jednak daleka od rzeczywistych funkcji zagnieżdżonych. W “prawdziwym” wydaniu mają one bowiem jedną ważną właściwość: posiadają dostęp do zmiennych lokalnych funkcji, w których są zawarte. W naszym przykładzie “funkcja” Square powinna więc móc odwołać się do (ewentualnych) zmiennych lokalnych z funkcji Distance. A ponieważ Square jest tutaj tak naprawdę obiektem jakiejś klasy, która nic nie wie o Distance, nie jest to rzecz jasna możliwe.
Czy możliwe jest więc, aby pełnowymiarowe funkcje zagnieżdżone pojawiły się np. w przyszłych wersjach języka C++?… Tutaj odpowiedź jest prawie na pewno negatywna. Jest tak dlatego, że obecność takich funkcji ingeruje bardzo głęboko w sposób, w jaki kompilator postępuje ze wszystkimi funkcjami. Pośrednimi konsekwencjami dodania funkcji zagnieżdżonych byłyby: niemożność korzystania ze standardowej konwencji wywoływania cdecl oraz zmiana wewnętrznej struktury wszystkich wskaźników na funkcje (które nie mogłyby być już pojedynczymi adresami).

Tags: ,
Author: Xion, posted under Programming » 19 comments

Wesołe jest życie admina

2008-12-23 21:01

Dwa komputery i jedno łącze internetowe to pewien kłopot, jeśli chcemy mieć dostęp do sieci na wszystkich maszynach jednocześnie. Istnieje oczywiście możliwość mostkowania (nazywanego w Windows udostępnianiem połączenia), ale wada tego rozwiązania jest znaczna: maszyny stają się od siebie zależne i jedna nie będzie miała dostępu do sieci bez drugiej. Na dłuższą metę jest to raczej niewygodne.
Aż dziwne, że dojście do tego wniosku zajęło mi ładnych parę miesięcy ;) W każdym razie nadarzyła się dobra okazja, by sytuację tę zmienić, więc parę dni temu zaopatrzyłem się w proste urządzenie sieciowe zwane potocznie routerem (chociaż faktycznie chodzi o switch routujący).

Przy tej okazji zauważyłem kilka dość zaskakujących dla mnie faktów. Ogólnie wygląda bowiem na to, że tworzenie domowych sieci stało się już tak bardzo powszechne, że urządzenia takie jak to nabyte przeze mnie są obecnie bardzo tanie. Za nieco ponad sto złotych można już mieć pudełko z powodzeniem radzące sobie ze sterowaniem ruchem w niewielkiej sieci, niekoniecznie przewodowej.
Druga niespodzianka związana była z tym, co było dołączone do urządzenia. Bo co niby może znajdować się na płycie CD, którą to – jak każe instrukcja – należy odczytać jeszcze przed podłączeniem routera? Raczej wątpliwe, by były to sterowniki :) Zagadka wyjaśniła się po zalogowaniu do panelu administracyjnego routera: otóż jest to sprytny programik, który odczytuje ustawienia komputera podłączonego bezpośrednio do Internetu, by potem skopiować je na router. Tym sposobem powinniśmy być w stanie skonfigurować urządzenie nawet wtedy, gdy ‘przeglądarka’ i ‘Internet’ to dla nas jedno i to samo… cóż, przynajmniej w teorii ;)

Oczywiście nie sprawdzałem tego w praktyce, bo zdecydowanie wolę tradycyjną metodę konfiguracji. To znacznie fajniejsze – podobnie zresztą jak dalsze grzebanie w ustawieniach routera i obserwowanie, jak to pakiety zdążają we właściwych sobie kierunkach :D

Tags: , ,
Author: Xion, posted under Internet, Life » 7 comments

Znów o testach jednostkowych

2008-12-18 21:04

Poprzednia notka o “rootkitach i innych nieszczęściach” zdołała utrzymać się długo, więc mogła stworzyć wrażenie, że cały czas źle się u mnie dzieje :) Nieprawda to oczywiście, więc wypadałoby w końcu coś na tę dezinformację poradzić.
Ostatnio cierpię na niewielki brak czasu spowodowany koniecznością dokładania nieco poważniejszych wysiłków co do pewnego dzieła, które docelowo ma zapewnić mi otrzymanie tytułu inżyniera informatyki. Z pewnych względów nie zdradzę, czym ono jest, ale pozwolę sobie wspomnieć o pewnych wnioskach, które przy okazji mi się nasunęły.

Parę miesięcy temu wypowiadałem się pochlebnie na temat testów jednostkowych, mając wtedy raczej niezbyt duże doświadczenie w ich stosowaniu. Dzisiaj jest już ono zdecydowanie większe i w związku z tym stwierdzić muszę, że… Nie, nie chcę powiedzieć, że wtedy myliłem się całkowicie ;P Chodzi raczej o równowagę zalet i wad.
To prawda, że unittesty dobrze sprawdzają się jako narzędzie znajdowania błędów i zapobiegania im. Do pewnego stopnia pomagają też w poprawianiu interfejsu tworzonych klas, tak aby ich użycie było wygodniejsze i bardziej intuicyjne. Te korzyści mają jednak swoją cenę, którą jest przede wszystkim czas poświęcony na pisanie owych testów – zwłaszcza w niektórych metodykach wytwarzania oprogramowania, które kładą na nie ogromny nacisk. Całkiem normalna jest bowiem sytuacja, że kod testowy jest dłuższy niż testowany (czasem nawet kilkakrotnie). Dodatkowo nie mamy przecież znikąd żadnej gwarancji, że ów testowy kod sam nie zawiera jakichś błędów… W sumie więc dochodzi nam sporo dodatkowej pracy w zamian za większą niezawodność tworzonego oprogramowania.
Drugi wniosek jest bardziej – że tak powiem – filozoficzny :) Otóż programowanie wedle zasady:

  1. while (!ProgramGotowy())
  2. {
  3.     NapiszTest();
  4.     do
  5.     {
  6.          NapiszLubPoprawKod();
  7.          UruchomTest();
  8.     } while (!TestPrzeszedl());
  9. }

może i jest efektywne, ale na dłuższą metę zaczyna się robić nużące i trochę zniechęcające. Pomyślmy jak łatwo jest pisać kod “rozgrzebany”, którego nie planujemy od razu kompilować i poprawiać tych wszystkich pomyłek, których kompilator nam zasygnalizuje. Porównajmy to z pisaniem kodu, który nie tylko jak najczęściej kompilujemy, ale i regularnie przepuszczamy przez własnoręcznie napisane testy! Toż to straszne, tak samemu kręcić na siebie bat :) Gdzie tu koderska wolność artystyczna? :D
Ale nie ma rady, czasami trzeba zakasać rękawy i testować…

Tags:
Author: Xion, posted under Programming, Studies, Thoughts » 6 comments

Rootkity i inne nieszczęścia

2008-12-05 11:42

Jedną z rzeczy, którą musiałem wykonać w trakcie (tymczasowej) przesiadki na komputer stacjonarny, było dogłębne sprawdzenie go programem antywirusowym – co “z pewnych względów” nie było czynione przez dobrych kilka miesięcy :) Skan nie wykrył aczkolwiek w zasadzie nic bardziej niebezpiecznego niż typowe ‘śledzące ciasteczka’ (tracking cookie). Dopiero później zaczęło się robić ciekawie.
Zło (i to przez duże Z) zostało bowiem wkrótce wykryte przez skaner działający w tle, który zidentyfikował je heurystycznie jako rootkit i oprócz tej informacji nie powiedział zresztą nic więcej. Przyznam, że było to moje pierwsze zetknięcie z tego typu szkodnikami, więc tym bardziej energicznie zabrałem się do rozwiązywania problemu – zwłaszcza że ze wszystkich typów złośliwego oprogramowania to właśnie rootkity sa zdecydowanie najgroźniejsze.
Na szczęście ten okazał się dość znanym i nawet nieszczególnie niebezpiecznym drobnoustrojem, przenoszącym się – o dziwo – nie przez sieć, lecz przez dyski wymienne. Zapewne dlatego też moje kilkugodzinne starcie z przeciwnikiem zakończyło się (prawdopodobnie) sukcesem, zaś wnioski z tego są następujące:

  • Antywirusy nie radzą sobie z rootkitami i zwykle potrafią jedynie zasygnalizować, że w systemie “coś siedzi”. Do wykrywania rootkitów istnieją dedykowane programy, których najlepiej jest używać grupowo, a i tak pozytywnym wynikom nie należy do końca ufać.
  • Google pomaga :) Jedną z dobrych metod identyfikacji niechcianych programów jest bowiem przejrzenie listy procesów (stworzonej przez narzędzie w rodzaju IceSword) i kolejne sprawdzenie wszystkich potencjalnie podejrzanych pozycji poprzez wyszukanie informacji na ich temat w Internecie.
  • Najbardziej znanym narzędziem do usuwania rootkitów jest ComboFix, który pomógł zresztą w moim przypadku. W ogólności jednak naprawa może być niemożliwa. Tak naprawdę zaleca się zresztą, by po wykryciu rootkita poważnie zastanowić nad sformatowaniem dysku i odbudową systemu od podstaw. Brr :)

Krótko mówiąc, wykrywanie i walka z tym rodzajem szkodliwego oprogramowania to coś znacznie poważniejszego niż wciśnięcie przycisku Scan i czekanie na wyniki :] Rezultaty też nigdy nie są pewne.

O reinstalacji systemu na komputerze stacjonarnym trzeba więc będzie pomyśleć jak najszybciej, a od wczoraj stało się to prostsze, gdyż mój laptop wrócił z naprawy. Okazało się, że konieczna była wymiana płyty głównej (!) – oryginalna prawdopodobnie miała fabryczną usterkę… No cóż, dobrą stroną jest to, że za tę skomplikowaną operację nie musiałem zapłacić ani grosza; niech żyją gwarancje :)

Tags:
Author: Xion, posted under Applications, Life » 11 comments

Coś się zepsuło

2008-11-28 21:00

No to wykrakałem… Niecały rok temu pozwoliłem sobie ironizować na temat dziwnych przypadków dotykających komputery w Ministerstwie Sprawiedliwości, a teraz przytrafiło mi się coś w pewnym stopniu podobnego. No, może nie do końca – wprawdzie na pierwszy rzut oka mój przenośny komputer nadal wydaje się cały, ale trudno go nazwać działającym. Pewnego razu parę dni temu po prostu bardzo ładnie się zwiesił, zaś po sprzętowym restarcie nie okazuje żadnych znaków życia poza migającą kontrolką zasilania.
Na szczęście istnieją jeszcze serwisy gwarancyjne, które teoretycznie potrafią uporać się z każdą naprawą w średnio dwa tygodnie. Cokolwiek się więc zepsuło (strzelam w przegrzanie karty graficznej lub procesora), powinno zostać naprawione w jakimś rozsądnym czasie. A zanim tak się stanie, muszę przeprosić się z nieco zaniedbanym komputerem stacjonarnym :)

Tags: ,
Author: Xion, posted under Life » 8 comments

Cztery lata WoW-a

2008-11-23 21:01

Właśnie dzisiaj mijają dokładnie cztery lata od premiery pewnej gry, która chyba na długie lata pozostanie wzorcem w swoim gatunku – czyli World of Warcraft produkcji Blizzarda. Całkiem zresztą możliwe, że jest to też najlepiej zarabiająca gra w całej historii komputerowej rozrywki, a z pewnością najbardziej znana i najpopularniejsza (11 milionów graczy) produkcja z rodzaju MMORPG.
Wśród tych wszystkich “najów” tym bardziej zaskakujące jest też to, że granice dalszego wzrostu popularności WoW-a wcale nie wydają się być nie tyle nawet osiągnięte, co wręcz osiągalne w przewidywalnej przyszłości. Wystarczy chociażby spojrzeć na wyniki sprzedaży niedawno wydanego (w zeszłym tygodniu) dodatku Wrath of the Lich King. Nie da się zresztą ukryć, że Blizzard dwoi i się troi, aby wszyscy grający w WoW-a mieli co robić w wirtualnym świecie. Rezultaty bywają czasami zabawne; zalicza się do nich na przykład fakt, że wszystkie dungeony wchodzące w skład wspomnianego dodatku zostały ‘wyczyszczone’ już w… 2 dni od jego wydania. To na pozór nielogiczne, ale takie obniżenie poziomu trudności ma jak najbardziej sens. W końcu gracze casualowi i hardcore‘owi płacą po tyle samo, ale tych pierwszych jest przecież kilka(naście) razy więcej niż drugich. Nic więc dziwnego, że (niemal) cała treść gry zaczyna być kierowana właśnie do nich.

Czy na dłuższą metę (czyli przynajmniej następne cztery lata) okaże się to dobrą strategią, nie sposób przewidzieć. Póki co nic nie wskazuje jednak na to, aby było inaczej. Mimo spadku znaczenia PC-tów i postępu technologicznego, oświetlany per vertex świat Azeroth przetrwa więc pewnie jeszcze bardzo, bardzo długo :)

Tags:
Author: Xion, posted under Games » 10 comments

Moc breakpointów w VS

2008-11-21 20:28

Śledzenie wykonywania programu to świetna metoda na znajdowanie przyczyn wielu błędów. Ale żeby coś sensownie śledzić, to najpierw zwykle trzeba dojść do interesującego fragmentu kodu – to zaś umożliwiają punkty przerwania, czyli po polsku breakpointy ;)
W najbardziej podstawowej wersji działają one niezwykle prosto i zwyczajnie zatrzymują debuger na wskazanej instrukcji. W Visual Studio możemy jednak wykorzystać w sposób znacznie bardziej zaawansowany; wystarczy bowiem – po postawieniu breakpointa kliknąć weń prawym przyciskiem myszy i już ukazuje się nam wielce interesujące menu podręczne. Mamy tam kilka przydatnych opcji, do których należą między innymi:

  • Location – umożliwia precyzyjne określenie, na jakiej instrukcji stawiamy breakpoint. Jest to użyteczne, gdy mamy np. krótką jednolinijkową instrukcję if, a punkt przerwania chcemy ustawić nie na sprawdzaniu jej warunku, lecz w środku jej bloku.
  • Hit Count – wyświetla nam okienko, w którym widać, ile razy breakpoint został “trafiony” od początku sesji debuggera. Możemy też określić tam, aby zatrzymanie następowało tylko przy jakimś określonym przejściu przez breakpoint. Może to być przydatne, jeśli np. debugujemy pętle, o której wiemy, że zaczyna się psuć w okolicach 4867 iteracji – właśnie tyle wciśnięć F5 możemy w ten sposób oszczędzić :)
  • When Hit – ta opcja pozwala z kolei na wykonanie dodatkowych akcji w momencie trafienia breakpointa, co obejmuje nawet możliwość uruchomienia makra sterującego zachowaniem IDE (!). Prawdopodobnie bardziej przydatne jest jednak wypisywanie komunikatu w oknie Output debugera; opcja ta jest na tyle zaawansowana, że może właściwie eliminować użycie funkcji typu OutputDebugString czy nawet dedykowanych logerów.
  • Condition to z kolei bodaj najprzydatniejsza opcja ze wszystkich. Pozwala mianowicie na określenie dodatkowego warunku, który musi być spełniony, aby punkt przerwania zadziałał. Jest to nieocenione do znajdowania błędów w skomplikowanych pętlach warunkowych, że o funkcjach rekurencyjnych nie wspomnę.
  • Filter to z kolei zaawansowana opcja, umożliwiająca ograniczenie działania breakpointa tylko do wybranych procesów lub wątków (rozpoznawanych przez identyfikator lub nazwę). Jak nietrudno się domyślić, przydaje się w programach równoległych.
  • W końcu Disable Breakpoint pozwala czasowo wyłączyć breakpoint bez usuwania go, czyli utraty tych wszystkich ustawień, które pieczołowicie wpisywaliśmy przy pomocy powyższych opcji :)

I tyle właśnie potrafią breakpointy w VS. Całkiem sporo, jak na jedną niepozorną, czerwoną kropkę :]

Tags: ,
Author: Xion, posted under Applications, Programming » 4 comments
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.