-
11. Data: 2018-11-16 23:55:24
Temat: Re: Niezmienniki pętli
Od: Maciej Sobczak <s...@g...com>
> (Ale też jeśli mam wybór, wolę myśleć w oparciu o równania rekurencyjne,
> niż imperatywne pętle)
Spotkałem się z opinią (i się z nią zgadzam), że wtedy rolę niezmienników pełnią pre-
i post-conditions w tych rekurencyjnych funkcjach. Pytanie, któro z nich jest łatwiej
wyrazić. I nadal, czy się to stosuje.
--
Maciej Sobczak * http://www.inspirel.com
-
12. Data: 2018-11-17 14:58:33
Temat: Re: Niezmienniki pętli
Od: Sebastian Biały <h...@p...onet.pl>
On 16/11/2018 23:55, Maciej Sobczak wrote:
> Spotkałem się z opinią (i się z nią zgadzam), że wtedy rolę niezmienników pełnią
pre- i post-conditions w tych rekurencyjnych funkcjach. Pytanie, któro z nich jest
łatwiej wyrazić. I nadal, czy się to stosuje.
Ja stosuje asercje i to raczej proste acz często sprawdzam stany z
gatunku "kontener musi być wypełniony" czy "indeks nie przekracza max
element", "liczba musi być ujemna" itd. Zasada jest taka że jeśli kod
kontrolujący stan miałbym mieć więcej linijek niż goły algorytm to
*zaciemnia* kod, dodatkowo niektóre checkery powodują wzrost złożoności
co może doprowadzić w końcowym efekcie do wzrostu czasu wykonania poza
rosądek (np. uniemożliwić debug). Po jakiś 20 latach stukania w klawisze
widziałem kod opakowany DbC po brzegi i wymagał on niesłychanie dużo
czasu aby zorientować się gdzie jest algorytm a gdzie checkery. Znacznie
bardziej ufam unit testom i coverage niż ręcznie pisanym DbC. Być może
to jednak efekt języka, czyi w moim przypadku C++, nie wykluczam że
można to czytelniej zapisać gdzie indziej.
-
13. Data: 2018-11-17 16:59:18
Temat: Re: Niezmienniki pętli
Od: s...@g...com
> >> Czyli twoim zdaniem lepiej, gdy program działa dalej na błędnych danych i
> >> w sposób, którego nie przewidział programista, niż gdy wypisze komunikat
> >> o błędzie wraz z lokalizacją, niespełnionym warunkiem i np. innymi
> >> informacjami diagnostycznymi i zakończy się, nie robiąc szkód?
> >>
> >> Bo wiesz, oprogramowanie się testuje, takie błędy wychodzą i takie błędy
> >> się poprawia, zamiast ignorować.
> >
> > Czytaj ze zrozumieniem:
> >> 5.1. Wierzę w try, throw, catch (wyjątki obowiązkowo dziedziczone po
std::exception z opisem i kodem błędu).
>
> Ok, to spytam inaczej: czym, wg ciebie, jest asercja?
>
> (dla uproszczenia: mówię o asercji sprawdzanej w czasie wykonania, nie o
> statycznej, sprawdzanej w czasie kompilacji)
Czytaj ze zrozumieniem:
> 5.2. Nie wierzę w i nie cierpię Assert (to tak jak by bez ostrzeżenia uderzyć kogoś
w twarz bez dalszego komentarza).
-
14. Data: 2018-11-18 00:10:13
Temat: Re: Niezmienniki pętli
Od: Maciej Sobczak <s...@g...com>
> Zasada jest taka że jeśli kod
> kontrolujący stan miałbym mieć więcej linijek niż goły algorytm to
> *zaciemnia* kod
Tak, to ważna obserwacja. Może da się te rzeczy rozdzielić? Tak jak rozdziela się
interfejs od implementacji? Zwłaszcza wtedy, gdy jakieś warunki faktycznie należą do
interfejsu? Akurat niezmienniki pętli należą do implementacji (i potrafią pięknie
zaciemnić kod), ale takie rzeczy jak "parametr powinien być między 0 a 20" albo
"wartość zwracana powinna być w zakresie indeksów tablicy" to intefejs. I może da się
to wtedy zapisać gdzieś w okolicy deklaracji tak, żeby użytkownik to widział (i mógł
się pod to sprawdzić)? Tak działa SPARK i przyznam, że podoba mi się.
> Po jakiś 20 latach stukania w klawisze
> widziałem kod opakowany DbC po brzegi i wymagał on niesłychanie dużo
> czasu aby zorientować się gdzie jest algorytm a gdzie checkery.
Czy czytelność kodu nie jest też kwestią umiejętności piszącego? Nie zawsze sama
koncepcja programistyczna musi ją przekreślać. Tzn. to nie musi być wina DbC, że kod
jest nieczytelny.
> Znacznie
> bardziej ufam unit testom i coverage niż ręcznie pisanym DbC.
W porządku. Testy też są potrzebne. A co jeśli część DbC można sprawdzić statycznie?
Wtedy ich wartość jest inna, niż testów. A co jeśli wtedy można by niektórych testów
w ogóle nie mieć? Unit testy to też koszt. Jeśli można tego kosztu nie mieć, to jest
to wartość dodana.
> Być może
> to jednak efekt języka, czyi w moim przypadku C++, nie wykluczam że
> można to czytelniej zapisać gdzie indziej.
A może wtedy należy odwrócić kolejność i zamiast szukać języka, gdzie to jest
czytelne (albo zamiast doklejać DbC do używanego języka), można taki język zrobić? W
sensie - zamiast rezygnować z DbC, bo jest nieczytelny, zróbmy język tak, żeby to
było czytelne.
To nie są zupełnie teoretyczne pytania.
--
Maciej Sobczak * http://www.inspirel.com
-
15. Data: 2018-11-18 01:02:44
Temat: Re: Niezmienniki pętli
Od: q...@t...no1 (Queequeg)
s...@g...com wrote:
>> Ok, to spytam inaczej: czym, wg ciebie, jest asercja?
>>
>> (dla uproszczenia: mówię o asercji sprawdzanej w czasie wykonania, nie o
>> statycznej, sprawdzanej w czasie kompilacji)
>
> Czytaj ze zrozumieniem:
>> 5.2. Nie wierzę w i nie cierpię Assert (to tak jak by bez ostrzeżenia uderzyć
kogoś w twarz bez dalszego komentarza).
Dopytuję bo mam wrażenie, że masz bardzo mgliste pojęcie o tym, czym jest
asercja.
O static assert słyszałeś?
--
https://www.youtube.com/watch?v=9lSzL1DqQn0
-
16. Data: 2018-11-18 09:58:56
Temat: Re: Niezmienniki pętli
Od: AK <n...@n...net>
On 2018-11-18 00:10, Maciej Sobczak wrote:
>> Zasada jest taka że jeśli kod
>> kontrolujący stan miałbym mieć więcej linijek niż goły algorytm to
>> *zaciemnia* kod
>
> Tak, to ważna obserwacja. Może da się te rzeczy rozdzielić? Tak jak rozdziela się
interfejs
> od implementacji? Zwłaszcza wtedy, gdy jakieś warunki faktycznie należą do
interfejsu? Akurat
> niezmienniki pętli należą do implementacji (i potrafią pięknie zaciemnić kod), ale
takie rzeczy
> jak "parametr powinien być między 0 a 20" albo "wartość zwracana powinna być w
zakresie indeksów
> tablicy" to intefejs. I może da się to wtedy zapisać gdzieś w okolicy deklaracji
tak, żeby
> użytkownik to widział (i mógł się pod to sprawdzić)? Tak działa SPARK i przyznam,
że podoba
> mi się.
Np. w Pythonie do takich rzeczy (DBC) dobrze nadają sie dekoratory
funkcji/metod/klas (ich dzialanie jes o wiele szersze/bardziej
dynamiczne niz dekoratory/annotacje z innych jezykow programowania
np.Javy).
>> Po jakiś 20 latach stukania w klawisze
>> widziałem kod opakowany DbC po brzegi i wymagał on niesłychanie dużo
>> czasu aby zorientować się gdzie jest algorytm a gdzie checkery.
>
> Nie zawsze sama koncepcja programistyczna musi ją przekreślać.
> Tzn. to nie musi być wina DbC, że kod jest nieczytelny.
Racja.
> A może wtedy należy odwrócić kolejność i zamiast szukać języka, gdzie to jest
> czytelne (albo zamiast doklejać DbC do używanego języka), można taki język zrobić?
> W sensie - zamiast rezygnować z DbC, bo jest nieczytelny, zróbmy język tak,
> żeby to było czytelne. To nie są zupełnie teoretyczne pytania.
..czasem wystarczy w danym jezyku dobrze to zaiplementowac.
Np. w Pythonie "od lat" stosuję zope.interface i bardzo sobie chwalę
https://pypi.org/project/zope.interface/
https://zopeinterface.readthedocs.io/en/latest/
np.
https://zopeinterface.readthedocs.io/en/latest/READM
E.html#invariants
AK
-
17. Data: 2018-11-18 10:10:20
Temat: Re: Niezmienniki pętli
Od: fir <p...@g...com>
W dniu piątek, 16 listopada 2018 16:48:18 UTC+1 użytkownik s...@g...com napisał:
> > Czy w związku z tym zagadnienie niezmienników jest niepotrzebne? A może nadal
jest potrzebne i coś innego je zastępuje?
>
> 1. Wiedziałem co to jest.
>
> 2. Stosuję
>
> 3. Sam też stosujesz
>
> Najprostrze zastosowanie:
> QList<int> lList = {0, 1, 2, 3, 4, 5};
> for(int i(0); i < lList.size(); ++i)
> // tu robisz coś z lList
> W tej pętli niezmiennikiem sprawdzanym przed wejściem w pętlę i po kazdej iteracji
jest:
> i < lList.size()
>
> Nieco bardziej ogólne jest:
> QList<int> lList = {0, 1, 2, 3, 4, 5};
> for(int& lItem : lList)
> // tu robisz coś z lItem
> W tym przypadku niezmiennikiem (ukrytym) jest fakt iteracji po wszystkich
elementach listy.
>
> 4. Zazwyczaj dalszych niezmienników w pętli nie sprawdzam. Głównie ze względu na 2
wady:
> 4.1. Puchnięcie i zaciemnianie kodu.
> 4.2. Spowolnienie programu.
>
> 5. Bardzo często sprawdzam parametry wejściowe funkcji (wierzę i stosuję coś w
rodzaju programowania kontraktowego).
> 5.1. Wierzę w try, throw, catch (wyjątki obowiązkowo dziedziczone po std::exception
z opisem i kodem błędu).
> 5.2. Nie wierzę w i nie cierpię Assert (to tak jak by bez ostrzeżenia uderzyć kogoś
w twarz bez dalszego komentarza).
> 5.3. Toleruję wartości zwracane (jako informacje o błędach) i brak standaryzacji w
dostępie do opisów błędów w Qt.
ostatnio odkrylem dosyc odkrywczy sposob
dilowania (tj forme kodowanie obslugi bledow) z bledami w jezykach podobnych
do c
wymaga on pewnej poprawki do jezyka,
(i jest opisany na clc, troche nie che mi sie tu opisywac bo nie lubie sie powtarzac)
jest on ogolnie ciekawy bo mz pokazuje co to jest normalne dilowanie z bledami i na
czym to normalne dilowanie z bledami normalnie polega (ma polegac)
nawiasem mowiac w swietle tego asercje
albo bledy przypadkowe (jak np zmienienie sie jakiejs komorki w rami i wyjatek typu
nielegalna instrukcja) nie sa normalnymi sposobami dilowania z bledami tylko pewnymi
case'ami nadspecjalnymi
NORMALNY i najbardziej typowy sposob z
handlowaniem z bledami w programie to zwykle zwrocenie informacji o bledzie do
funkcji w tyl - tylko ze nie powinno to byc mieszane ze zwracaniem poprawnej wartosci
w tym kanale w ktorym zwraca sie wartosci w sytuacjach niebledowych..
dzis jesli ktos zwraca blad w tyl (jak rozne api robia) to ogolnie robi dobrze,
tylko ze jesli wtyka kody bledow w wartosci zwracane to zarazem robi zle ;c
https://groups.google.com/forum/#!topic/comp.lang.c/
p1CcmgZKkV4
-
18. Data: 2018-11-18 10:28:51
Temat: Re: Niezmienniki pętli
Od: fir <p...@g...com>
W dniu niedziela, 18 listopada 2018 10:10:22 UTC+1 użytkownik fir napisał:
> W dniu piątek, 16 listopada 2018 16:48:18 UTC+1 użytkownik s...@g...com
napisał:
> > > Czy w związku z tym zagadnienie niezmienników jest niepotrzebne? A może nadal
jest potrzebne i coś innego je zastępuje?
> >
> > 1. Wiedziałem co to jest.
> >
> > 2. Stosuję
> >
> > 3. Sam też stosujesz
> >
> > Najprostrze zastosowanie:
> > QList<int> lList = {0, 1, 2, 3, 4, 5};
> > for(int i(0); i < lList.size(); ++i)
> > // tu robisz coś z lList
> > W tej pętli niezmiennikiem sprawdzanym przed wejściem w pętlę i po kazdej
iteracji jest:
> > i < lList.size()
> >
> > Nieco bardziej ogólne jest:
> > QList<int> lList = {0, 1, 2, 3, 4, 5};
> > for(int& lItem : lList)
> > // tu robisz coś z lItem
> > W tym przypadku niezmiennikiem (ukrytym) jest fakt iteracji po wszystkich
elementach listy.
> >
> > 4. Zazwyczaj dalszych niezmienników w pętli nie sprawdzam. Głównie ze względu na
2 wady:
> > 4.1. Puchnięcie i zaciemnianie kodu.
> > 4.2. Spowolnienie programu.
> >
> > 5. Bardzo często sprawdzam parametry wejściowe funkcji (wierzę i stosuję coś w
rodzaju programowania kontraktowego).
> > 5.1. Wierzę w try, throw, catch (wyjątki obowiązkowo dziedziczone po
std::exception z opisem i kodem błędu).
> > 5.2. Nie wierzę w i nie cierpię Assert (to tak jak by bez ostrzeżenia uderzyć
kogoś w twarz bez dalszego komentarza).
> > 5.3. Toleruję wartości zwracane (jako informacje o błędach) i brak standaryzacji
w dostępie do opisów błędów w Qt.
>
> ostatnio odkrylem dosyc odkrywczy sposob
> dilowania (tj forme kodowanie obslugi bledow) z bledami w jezykach podobnych
> do c
>
> wymaga on pewnej poprawki do jezyka,
>
> (i jest opisany na clc, troche nie che mi sie tu opisywac bo nie lubie sie
powtarzac)
>
> jest on ogolnie ciekawy bo mz pokazuje co to jest normalne dilowanie z bledami i na
czym to normalne dilowanie z bledami normalnie polega (ma polegac)
>
> nawiasem mowiac w swietle tego asercje
> albo bledy przypadkowe (jak np zmienienie sie jakiejs komorki w rami i wyjatek typu
nielegalna instrukcja) nie sa normalnymi sposobami dilowania z bledami tylko pewnymi
case'ami nadspecjalnymi
>
> NORMALNY i najbardziej typowy sposob z
> handlowaniem z bledami w programie to zwykle zwrocenie informacji o bledzie do
funkcji w tyl - tylko ze nie powinno to byc mieszane ze zwracaniem poprawnej wartosci
w tym kanale w ktorym zwraca sie wartosci w sytuacjach niebledowych..
>
> dzis jesli ktos zwraca blad w tyl (jak rozne api robia) to ogolnie robi dobrze,
> tylko ze jesli wtyka kody bledow w wartosci zwracane to zarazem robi zle ;c
>
> https://groups.google.com/forum/#!topic/comp.lang.c/
p1CcmgZKkV4
albo ok niech, bedzie opisze po polsku
sposob polage on na tym
int x = foo(20,10) on error { printf("error"); }
polaga on na tym ze wywolanie kazdej funkcja ktora moze zwrocic error powinno
obsluzyc branch tj wstawic tam dowolny kod do obslugi bledu
po stronie ciala funkcji wyglada to tak ze, wychodzisz z funkcji nie przez return ale
inne slowo kluczowe np error
int foo(int a, int b)
{
if(a<b) error;
return a-b;
}
implementacja, ustawiasz po wyjsciu z funkcji jakas flage, np carry, zero czy cos w
tym stylu
niektore zalety
1. musisz jawnie napisac klauzule obslugi bledu (zacheca do klarownej obslugi)
2. w ciele wolanej funkcji obsluga bledow jest dosyc jasna i klarowna (zacheca do
klarownej obslugi)
obie strony zachecaja do klarownej obslugi, po prostu kodowanie bledow jako
normalnych stanow programu do czego obecne c jakos nie zacheca
jest to wielka zaleta ... kody sa bardziej kompletne, moga byc 'zamniete na bledy'
3. nie mieszasz wartosci zwracanej i kodu bledu (to mieszanie to syf)
jest to wielka zaleta ... kody sa czystsze
4. skladania jest wzglednie ladna (moze poprobuje poprawic to wyzej to draft)
(napewno sprobuje poprawic bo to zarys, nie wiem np co z tymi domyslnymi sygnalami,
tj ze skladnia do tego o czym troche nizej)
5.jest szybkie w runtime (chyba szybciej nie mozna, nie jestem pewien, kiedys mozna
pomyslec)
6, rozwiazuje duzo abstrakcyjnego chaosu, bo ludzi zastaawiaja sie jak dilowac z
bledami to jest tak naprawde poprawny sposob
to jest tez duza zaleta boludzi emaja sporo problemow ze zrozumieniem co robic z
bledami - to co ja tutaj proponuje jest tak naprawde dosyc poprawneym rozwiazaniem -
zwracasz bald wyzej, kod wywolywacza podejmie decyzje
dopuszczam lub rozwazam jeszcze opcje dla super leniwych, opcje opuszczania tych
klauzul (ew jakiegos zaznaczania ze sa opuszczane, nie ejestem pewien) w takim
wypadku, na kazdy zwrocony a nie zbranczowany blad lecialby sygnal do
zarejsetrowanego handlera eventow - co tez jest wygodne jak ktos jest superleniwy
pytaniem jest troche 1) czy dopuszczac opuszczanie tych branczy czy raczej to
poprostu zawsze wymuszac (do tego zdanie moga byc podzielone, ale raczej wydaje sie
ze na specjalna prosbe autora kodu przynajmniej (jakas opcja kompilaci czy cos nalezy
na o dozwolic)) 2) drygie pytanie czy na takie opuszczenie kompletnie ignorowac te
brancze czy zmuszac do oznaczania jakims prostym slowem , chocby "SIG" zeby bylo
wiadome
ze blad teoretycznie moez poleciec 3)
trzecie pytanie co robic w wypadku gdy taki nieobsluzony blad poleci,
najrozsadzniejsza opcja chyba wydaje sie wywalanie signal handlera z jakims domyslnym
kodem w tym handlerze (typu wywalenie message boxa z informacja
"error taki a taki w funkcji takiej a takiej zwrocony przez funkcje taka a taka,
nacisnij ok by zamknac program (ignoruj by zignorowac?"
lekko otwarta kwestia jest tez w jakis sporob te polecenie arror powinny zwracac info
o bledzie oraz co robic z wartoscia zwracana w tym wypadku (w duchu starego c
znaczyloby chyba ze jest undefined, ale ew mozna wymyslec cos innego)
-
19. Data: 2018-11-18 17:35:46
Temat: Re: Niezmienniki pętli
Od: Sebastian Biały <h...@p...onet.pl>
On 18/11/2018 00:10, Maciej Sobczak wrote:
>> Zasada jest taka że jeśli kod
>> kontrolujący stan miałbym mieć więcej linijek niż goły algorytm to
>> *zaciemnia* kod
> Tak, to ważna obserwacja. Może da się te rzeczy rozdzielić?
To następna obserwacja: jeśl wpływa to na runtime release należy to
odrzucić. Wszelakie checkery asercyjne, za wyjątkiem programowania
defensywanego, nie mogą istnieć w kodzie produkcyjnym. Z marginesem
dyskusji o językach w których jest kłopot z warunkową kompilacją.
>> Po jakiś 20 latach stukania w klawisze
>> widziałem kod opakowany DbC po brzegi i wymagał on niesłychanie dużo
>> czasu aby zorientować się gdzie jest algorytm a gdzie checkery.
> Czy czytelność kodu nie jest też kwestią umiejętności piszącego?
Jest, ale w przypadku nadmiaru checkerów nie da się pisać czytelnie.
Nazjwyczajniej nie widać gdzie jest algorytm w morzu makr, asercji czy
fake funkcji. Widziałem kiedyś IDE które klapsowało asercje. Niestety
tylko asercje.
> Nie zawsze sama koncepcja programistyczna musi ją przekreślać. Tzn. to nie musi być
wina DbC, że kod jest nieczytelny.
Tak, ale nadmiar DbC generuje zaciemnienie kodu. Taki smutny praktyczny
wniosek. Biorę jednak pod uwagę że pracuje z toksyczym językiem.
>> Znacznie
>> bardziej ufam unit testom i coverage niż ręcznie pisanym DbC.
> W porządku. Testy też są potrzebne. A co jeśli część DbC można sprawdzić
statycznie?
Potrzebujemy kompilator który to by potrafił :) Jakiś porządny lint. Mój
język, C++, ma wyjątkowo popieprzony problem z side effects i kiesko
widzę kontrole DbC na poziomie statycznej analizy kodu. Może dla
prostych przypadków, ale takich za dużo nie ma.
> A co jeśli wtedy można by niektórych testów w ogóle nie mieć?
Dlatego używam np metaprogramowania do kontrolownia różych obliczeń.
Jednak dalej brakuje mi czegoś takiego jak int a<4-200> i kontroli
komilatora w debug kiedy a zmieni się poza zakres. Contraints by się
przydało i już powoduje to zniknięcie kilku lini DbC.
>> Być może
>> to jednak efekt języka, czyi w moim przypadku C++, nie wykluczam że
>> można to czytelniej zapisać gdzie indziej.
> A może wtedy należy odwrócić kolejność i zamiast szukać języka, gdzie to jest
czytelne (albo zamiast doklejać DbC do używanego języka), można taki język zrobić?
Nie. Poza przypadkami jak clojure nie znam w zasadzie nic co mogło by
być uznane za projekt języka do potrzeb. Języki które są popularne mają
bibliteki, języki wymyślane nie. Na sam koniec wyjądujesz projektując
jeszcze jeden niszowy język na bytecode javy i z nią kompatybilny
którego nikt nie użyje poza helloworld.
Obserwuje że ludzie nie chcą języków bezpiecznych. Potrzebują zabawek
typu python albo stosu kupy typu perl i są zadowoleni.
> W sensie - zamiast rezygnować z DbC, bo jest nieczytelny, zróbmy język tak, żeby to
było czytelne.
> To nie są zupełnie teoretyczne pytania.
Język ten nie zdobedzie popularnosci. Wolałbym dodanie czegoś do
istniejących języków.
Na początek chciabym w C++ takie coś:
debug {
// O(N^2) checker
}
I ide kolapsujący te sekcje.
-
20. Data: 2018-11-19 08:14:44
Temat: Re: Niezmienniki pętli
Od: Maciej Sobczak <s...@g...com>
> > Tak, to ważna obserwacja. Może da się te rzeczy rozdzielić?
>
> To następna obserwacja: jeśl wpływa to na runtime release należy to
> odrzucić.
więc odrzućmy. Niech sobie będą statyczne asercje oraz dynamiczne, ale sterowane
opcjami kompilatora.
> Jest, ale w przypadku nadmiaru checkerów nie da się pisać czytelnie.
[...]
> Jednak dalej brakuje mi czegoś takiego jak int a<4-200>
Czyli ogólnie: type invariants (niezmienniki typów). Wtedy warunek poprawności dla
danego typu opisuje sie w jego definicji i nie trzeba już zaciemniać kodu pisząc co
chwilę asercje, czy obiekt ma dobry stan. Tzn. zminimalizujmy zaciemnienie zbierając
je do jednego miejsca, z dala od algorytmu.
Ciekawe, że wtedy można odróżnić niezmienniki typów (takie jak zakres zmiennej) od
niezmienników obliczeń (np. pętli) i wraz z tym rozróżnieniem dać im osobne miejsce w
kodzie. Przecież nie wszytko musi być klasycznym assertem.
> Contraints by się
> przydało i już powoduje to zniknięcie kilku lini DbC.
Chyba mamy to samo na myśli.
> Obserwuje że ludzie nie chcą języków bezpiecznych.
Zgadza się.
> Na początek chciabym w C++ takie coś:
>
> debug {
> // O(N^2) checker
> }
Wystarczy rozszerzyć składnię asserta. W tej chwili assert musi dostać jedno
wyrażenie, ale można by go rozszerzyć tak, żeby akceptował dowolne fragmenty kodu. W
niektórych językach to się robi o tyle łatwiejsze, że wszystko jest albo może być
wyrażeniem, również pętla While czy cokolwiek innego - wtedy do takiego asserta można
wsadzić dowolny fragment kodu, nawet z własnymi definicjami zmiennych wykorzystanych
w środku. Ale w C++ chyba niewiele trzeba, żeby to osiągnąć, np. z taką składnią:
assert(dowolnyfragmentkodu, wynik_bool);
I użyć tego tak:
assert(
int i; // albo inne definicje
int j = x; // x jest na zewnątrz, ale widać go tutaj
while (orzemy_jak_możemy)
{
// obliczenia, wywołania funkcji, itd.
...
},
x > 0 && i < 10 // jakiś ostateczny warunek
);
I wtedy assert, tylko w trybie debug, wykonuje ten kod a na końcu sprawdza warunek
logiczny z drugiego swojego argumentu. W trybie release nic nie robi.
Kto zaproponuje definicję makra assert o takich zdolnościach?
--
Maciej Sobczak * http://www.inspirel.com