[ Ruka @ 13.10.2002. 14:03 ] @
Ako sam imao neki objekat koji je unisten sa Free ili Destroy kako to da kasnije otkrijem u kodu. Poredjenje sa nil ne resava to. Znam da imam FreeAndNil(NekiObjekat) ali da li mogu da odredim posle poziva destruktora?
[ silverglider @ 13.10.2002. 18:19 ] @
Uvek mozes sa Assign da proveris da je to 'postojeci' objekat ili si ga vec 'ubio'. Dakle, ako si ga vec negde 'otkacio', onda se sledeci FreeAndNil NECE izvrsiti:


If Assigned(NekiObjekat) then FreeAndNil(NekiObjekat);


Dakle, ako postoji kao objekat, ubice ga, ako ne postoji, nista se nece desiti.
[ -zombie- @ 16.10.2002. 02:44 ] @
nemoj nikad da unistavash objekat direktno sa Destroy()! za unistavanje objekta sluzi Free(), ili joh bolje FreeAndNil()..

elem, kada se pozove Free, on poziva destruktor (Destroy) i time oslobadja svu memoriju i ostale resurse.. ali vazno je znati da samim tim, objekat nije nilovan, tj, posle tog cina, promenjiva koja je pokazivala na objekat sada pokazuje na deo memorije koji nicemu ne sluzi, i ako pokusate da pristupite tom objektu ponovo preko te varijable, svasta se moze desiti (u najblazu ruku exceptioni na sve strane ;)

zato je najbolje uvek koristiti FreeAndNil() zato sto to oslobadja memoriju (poziva destruktor) i anulira objekat.

zato kasnije uvek mozes da proverish da li je objekat oslobodjen ili ne, sa Assigned(obj) ili obj<>nil (dodje mu na isto)..

sto se tice prethodnog odgovora, ispitivanje uslova nije potrebno. funkcija FreeAndNil() poziva metodu Free, a evo pogledajte kod metode Free:

Code:

// iz System.pas unita

procedure TObject.Free;
begin
..if Self <> nil then
....Destroy;
end;


dakle Free uvek proverava da li je objekat razlicit od nil, i ako jeste, ona ga oslobodi...
[ silverglider @ 17.10.2002. 09:13 ] @
Mozda nisam ja bio dovoljno jasan - ako sve svoje objekte 'ubija' sa konstrukcijom poput "if assigned(objekat) then freeandnil(objekat)" bice uvek siguran da je i objekat po ubijanju nilovan i ne mora vise da razmislja. Licno upotrebljavam assigned vise zbog (dobre) navike sa pointerima, nego zbog neoslanjanja na automatizam Free-a. Nakon par neprijatnih iskustava sa Kylixom, vise volim da budem siguran.

A i taj TObject.Free kod mene izgleda malo drugacije:
Code:

procedure TObject.Free;
asm
        TEST    EAX,EAX
        JE      @@exit
        MOV     ECX,[EAX]
        MOV     DL,1
        CALL    dword ptr [ECX].vmtDestroy
@@exit:
end;
[ -zombie- @ 18.10.2002. 01:46 ] @
pa to sto izgleda drugacije, ne mora da znaci da radi drugacije!

ako nisam basH mLogo zardjao u asembleru, i ako je intel asembler iole slican motorolinom (MC68000) to tamo znaci isto ono sto i kod mene.

vidish one prve dve linije. JE @@exit znaci, ako je "ono-malopre-testirano jednako nuli, skoci na @@exit" (prva linija naravno testira), a to bi u prevodu bilo, if self=nil then exit. svodi se na isto...
[ silverglider @ 18.10.2002. 09:16 ] @
Dobro, bre, pa nisam te nazvao lazovom, ne moras da se brecas toliko :) Samo opusteno. Namera mi je bila da skrenem paznju da ono sto pise u system.pas jedne verzije, ne mora da pise i u drugoj verziji.

E sad, posto smo istu vodu nekada gazili (seka assembler i sl. za mc68k), da te pitam nesto - vidim ja te prve dve linije i znam sta znaci JE (i JNE, JZ, JNZ, JBE, ...), ali ne pomenu ti nista oko te prve linije. Ako je adresa objekta automatski po pozivu procedure locirana u EAX registar, i testira ga sam sa sobom (da li je a=a ?), kazi mi kad taj test nece vratiti true ?
[ -zombie- @ 19.10.2002. 01:08 ] @
pa vidi, nisam bash toliko strucan..

ali, koliko se meni cini, TEST uporedjuje sa nulom, a postoji druga komanda koja uporedjuje medjusobno dva broja, a to je valjda CMP.

znam da nisam pomenuo prvi red, jer, kao sto si me procitao , nisam ga bash skroz razumeo.. ja sam mislio da si to lose prekucao..

ako to zaista tako pise, ne znam kako da ga citam. bash zato sto mislim da TEST uporedjuje sa nulom, uopste mi nije jasno zasto uopste tamo postoje dva operanda. ja bi tu ocekivao samo "TEST EAX"..

(sa druge strane, ako TEST zaista uporedjuje dva broja, slazem se sa tobom, ta linija koda nema nikakvog smisla.)

ako te bash toliko zanima, pitaj strucnjake sa asm foruma....
[ silverglider @ 19.10.2002. 01:41 ] @
Ma ne mislim da otkrivam Borlandu toplu vodu; koristim onako kako je napisano - ovo je bilo samo nadovezivanje na ono "sta pise u helpu i kako bi trebalo" i "kako to radi u praxi", posto sam i sam imao nekoliko neugodnih iskustava, bas na mestima gde ih nisam ocekivao, zbog toga sto sam se pouzdavao u neki automatizam biblioteke (i oni su ljudi i nekada grese). Zato vise volim nekada da otkucam red-dva vise i budem siguran, nego da razmisljam. Pogotovo kad radis na projektu od nekoliko desetina hiljada linija - debug negde na sredini razvoja i nije bas zabavan posao. BTW, ovo nisam prekucavao, nego samo copy/pasteovao iz system.pas-a Delphija petice, kao primer.
[ -zombie- @ 20.10.2002. 04:40 ] @
imam vrlo dobro, visegodisnje (dobro, samo oko dve-tri godine) iskustvo sa programima od par 10K linija koda. i sto je josh gore, sa programima na kojima je radilo po najmanje 3 coveka, sto je za debug SMRT!

jedno sto znam je da ako ne mozes da verujesh borlandu i njihovim standardnim bibliotekama, onda ne mozes da verujesh nikome! mislim, ako ja treba svaki posao da proverim dva puta, cemu onda sve to. onda idem da programiram u vb-i (necu, shalim se ;)

btw, cak i ako proverish tako nesto sto si ti napisao na taj nacin, ko ti garantuje da ta IF naredba radi dobro? ili nesto drugo? taj nacin koji si napisao (verovatno) proizvodi POTPUNO isti asm kod u exe fajlu...

ne zelim bash da polemisem mnogo na ovu temu. moj pvi post je samo bio da bi objasnio nekome sta sve to radi ispod haube, da bi ljudi imali bolje razumevanje za sistem. sa takvim dubljim znanjem, ljudi ce znati gde da ocekuju i traze gresku. mislim da dupla provera borlandovog koda nema mnogo smisla po definiciji. ako kompajler ne radi dobro, mozes ti da se slikash, ali ti se vise isplati da dizes ruke od programiranja...

inace, ne tvrdim da su ljudi iz borlanda nepogresivi (mada jesu najblize tome sto postoji ;) vec da nema smisla na svakom koraku traziti gresku u borlandovom kodu.

ovo pricam zbog mog prijatelja koji pokusava da programira u php-u, iako nije programer, i zbog prijateljice koja pokusava da programira u vb-u, isto neprogramer. redovno mi se zale, i obracaju za pomoc izjavama tipa "ovaj php ne radi kako treba" ili "ovaj vb je pun rupa". (sa ovim drugim mogu i da se slozim ;)

a svaki, ali SVAKi put, je bila neka njihova greska..

naravno nemoj da mislish da ja tebe uporedjujem sa njima, samo sam izneo primer...
[ silverglider @ 23.10.2002. 01:58 ] @
Ne, nisam mislio preispitivanje borlandovog koda u takvom smislu i/ili obimu. Ne pada mi napamet da sumnjam da li IF ili nesto slicno radi korektno i kakav asm kod generise. Licno nisam skoro nikada zavirivao u source biblioteke, dok nisam poceo da radim u Kylixu. E sad, posto je to bio na brzaka sklepani delphi za linux (ide radi pod wine emulatorom), to je padalo i pucalo k'o kisna godina. Prvo izdanje CLX-a (ne ispeglanog VCL-a), bagovi na sve strane. Kada ti najobicniji tcombobox ne radi kako si ocekivao, pogledaces u source biblioteke sigurno :) A tamo te ceka sijaset "todo" linija, pa cak i metoda (statickih) sastavljenih samo od "begin" i "end", dakle, ne kao abstract ili virtual :)
[ morlic @ 06.11.2002. 10:15 ] @
TEST instrukcija proverava da li je setovan neki bit ( AND )

U EAX- je adresa instance objekta.
Ako je EAX = 0 onda je pokazivac na instancu objekta NIL tj. ne pokazuje nigde i nema potrebe da se radi Destroy, a ako nije onda pozvati Destroy.

procedure TObject.Free;
asm
TEST EAX,EAX <----------- Testiraj EAX
JE @@exit < ----------- onda izadji iz procedure
MOV ECX,[EAX] < ----------- Ako nije onda...
MOV DL,1
CALL dword ptr [ECX].vmtDestroy < ---------- Pozovi Destroy
< ----------
@@exit:
end;
[ -zombie- @ 06.11.2002. 23:25 ] @
a sto ne objasni zasto se tu EAX pojavljuje dva puta?
[ morlic @ 07.11.2002. 16:31 ] @
U principu neki pointer moze biti NIL ( tj. da ima vrednost 0 ). TEST EAX, EAX ce evoulirati u skok samo ako je u EAX vrednost 0, jer je bilo koja druga vrednost potencijalno ispravan pokazivac. Kazem potencijalan zato sto se moze desiti da je instanca klase unistena ali da pokazivac i dalje drzi upamcenu adresu na kojoj je instanca bila. Zato je vrlo bitno da se pokazivac postavi na NIL posle poziva Free metode. Mozda su mogli da stave i neki drugaciji nacin ispitivanja, zasto su izabrali ovaj nisam siguran, mogu samo da pogadjam.
[ -zombie- @ 09.11.2002. 02:31 ] @
ok. hvala na odgovoru, ali mi nisi rekao nista novo. to sve znam.

ja (i silver) smo se pitali zasto tu stoji dva puta EAX. ja (i on) znamo motorolin asembler, i tamo postoje dve naredbe za ispitivanje, posle kojih ide je, jne, ili sta vec (u stvari na mc je bre, brn valjda ;)

jedna uporedjuje dve vrednosti, i prima (logicno) dva parametra: cmp a, b

druga uporedjuje jednu vrenost sa nulom, i prima jedan parametar: tst c

e sad, mi smo se pitali zasto tamo stoji dva puta eax? ako test radi isto sto i tst na motoroli, onda treba da stoji samo jedan parametar, a ako test radi isto sto i cmp, onda ce to uvek da izazove skok na sledecem je...
[ morlic @ 10.11.2002. 17:33 ] @
Pitanje je interesantno, ja sam razmisljao ali nemam odgovor. U MSDN-u sam nasao info o TEST instrukciji

<------------------------ START -------------------------- >

Sequence TEST value, value / Jcc location
Purpose Determine if a bit is set, and branch accordingly
Examples

TEST EAX,EAX
JNZ 00400124

TEST EDX,00400024
JZ 77f85624
Description The TEST instruction does a logical AND of the two arguments, which sets or clears the Zero flag in the EFLAGS register. The next instruction (JZ or JNZ) does a jump to the target address if the Zero flag is set or cleared, depending on the instruction used. If the JZ/JNZ doesn't jump, execution continues at the following instruction.
This sequence is typically used to test one or more bits as part of an if statement. For example, this C++ code could be implemented using a "TEST / JZ" sequence.

if ( MyVariable & 0x00400024 )
{
// Whatever code you want
}


If MyVariable has any of the same bitfields set as in the value 0x00400024, the Zero flag won't be set. This prevents the JZ instruction from jumping, and execution falls into the code in the curly brackets.

< --------------------------- KRAJ ------------------------------ >

Cak imaju i "TEST EAX, EAX" tako da to nije Borlandov specijalitet. :)
[ -zombie- @ 11.11.2002. 00:43 ] @
tek mi sad nista nije jasno ;)