Thread overview
Sınıf içerisinde opCmp kullanımı
Jan 21, 2013
Salih Dinçer
January 20, 2013

http://ddili.org/forum/thread/1063 adresinde bahsetmiş olduğum cmp ile test'in farkını şimdi daha iyi anladım.

Classlar ile çalışırken opcmp özelliğini kullanmam gerekti. Ve burada opcmp komutunun substract işlemi yaptığını kesinleştirmiş oldum.

Diğer adresteki konuda test in cmp den daha hızlı olduğunu görmüştük bunun sebebi test xor işlemi yapıyor bu da substract dan daha hızlı oluyor..

import std.stdio;
class sayi{
	int value;
	this(int value){
		this.value = value;
	}
	override int opCmp(Object T){
       return this.value - (cast(sayi) T ).value;
	}
}

void main(){
	auto a = new sayi(15);
	auto b = new sayi(10);

	writeln(a > b);

}

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 20, 2013

Alıntı:

>

cast(sayi)'nın geçerli olup olmadığını da denetlemek gerekir

Evet haklısınız ben bendeki karışık kodları basitleştirerek yazdım sadece orayı atlamışım. Normalde bunun kontrolü yapılıyor. Ama olur da birisinin ihtiyacı olur diye paylaşmak istedim.

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 20, 2013

cast(sayi)'nın geçerli olup olmadığını da denetlemek gerekir yoksa ilgisiz türler karşılaştırıldığında program parçalanma hatasına neden oluyor:

class Kedi
{
   string isim;
}
// ...
   auto k = new Kedi();

   if (a < k) {

Nedeni, cast(sayi) o durumda null üretiyor. Tabii senin durumunda benimki gibi anlamsız bir kod belki de hiç yazılmayacaktır. O zaman da bu durumu bir assert ile denetlemeni öneririm.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

January 21, 2013

Çok hoş...:)

Kodu biraz değiştirdim ve üstünde yer alan şu assembly kodunu elde ettim:
Alıntı:

>

'_Dmain:
push EBP
mov EBP,ESP
sub ESP,8
push EBX

; a sınıfı tanımlanıyor...
mov EAX,offset FLAT:SINIFIM@SYM32
push EAX
call _d_newclass@PC32 ; external
push 0Fh ; value = 15
call opCmpFunc@PC32
mov -8[EBP],EAX

; b sınıfı tanımlanıyor...
mov ECX,offset FLAT:SINIFIM@SYM32
push ECX
call _d_newclass@PC32 ; external
push 0Ah ; value = 10
call opCmpFunc@PC32
mov -4[EBP],EAX

; if(a > b) goto inc; else goto end;
add ESP,8
push EAX
mov EAX,-8[EBP]
mov EDX,[EAX]
call dword ptr 0Ch[EDX]
test EAX,EAX
jle END
mov EBX,-4[EBP]
INC:
inc dword ptr 8[EBX]
END:
xor EAX,EAX
pop EBX
leave
ret'

class SINIFIM {
   int value;

   this(int value) {
       this.value = value;
   }

   override int opCmp(Object T) {
       return this.value - (cast(sayi) T ).value;
   }
}

void main(){
   auto a = new SINIFIM (15);
   auto b = new SINIFIM (10);

   if(a > b) goto inc; else goto end;

   inc: b.value++;
   end: return;
}

Meğer sınıflar, bir adres defteri gibi aşağıdaki 'data segment'den oluşuyormuş. Sahip olduğu veriler üyelerin adresleri, değerleri vb.

Alıntı:

>

'.data segment
SINIFIM:
dd offset FLAT:_D14TypeInfo_Class6__vtblZ@SYM32
db 000h,000h,000h,000h ;....
db 00ch,000h,000h,000h ;....
dd offset FLAT:_D5opcmp4sayi6__initZ@SYM32
db 00ah,000h,000h,000h ;....
dd offset FLAT:_D5opcmp4sayi6__vtblZ[8]@SYM32
db 006h,000h,000h,000h ;....
dd offset FLAT:_D5opcmp4sayi6__vtblZ@SYM32
db 000h,000h,000h,000h,000h,000h,000h,000h ;........
dd offset FLAT:_D6Object7__ClassZ@SYM32
db 000h,000h,000h,000h ;....
db 000h,000h,000h,000h,03eh,000h,000h,000h ;....>...
db 000h,000h,000h,000h,000h,000h,000h,000h ;........
db 000h,000h,000h,000h,000h,000h,000h,000h ;........
db 000h,000h,000h,000h,000h,000h,000h,000h ;........
_D5opcmp12__ModuleInfoZ:
db 004h,008h,000h,0ffffff80h,000h,000h,000h,000h ;........
db 001h,000h,000h,000h ;....
dd offset FLAT:SINIFIM@SYM32
db 06fh,070h,063h,06dh,070h,000h,000h,000h ;opcmp...
db 000h,000h,000h,000h ;....
dd offset FLAT:_D5opcmp12__ModuleInfoZ@SYM32
db 000h,000h,000h,000h ;....
.data ends'

Asıl ilginç ve irdelenmesi gereken assembly kodu ise opCmp işlevi. Sanırım ovveride olduğu için önce bir temsilci sonra ise orada özelleştirilmiş kendi işlevimize yönleniyor olmalı. Burada da test komutu kullanılmış ve de fazladan çıkarma (sub) yapılmış!

'.text.opCmpFunc segment
assume CS:.text.opCmpFunc
opCmpFunc:
push EBP
mov EBP,ESP
sub ESP,4
mov ECX,8[EBP]
mov 8[EAX],ECX
leave
ret 4
text.opCmpFunc ends
text._D5opcmp4sayi5opCmpMFC6ObjectZi segment
assume CS:.text._D5opcmp4sayi5opCmpMFC6ObjectZi
_D5opcmp4sayi5opCmpMFC6ObjectZi:
push EBP
mov EBP,ESP
sub ESP,4
mov -4[EBP],EAX
test EAX,EAX
jne L2C
push 8
push dword ptr _TMP1@SYM32[015h]
push dword ptr _TMP1@SYM32[017h]
push dword ptr _D5opcmp4sayi6__vtblZ@SYM32[01h]
push dword ptr _D5opcmp4sayi6__vtblZ@SYM32[03h]
call _d_assert_msg@PC32
L2C: call _D9invariant12_d_invariantFC6ObjectZv@PC32
mov EAX,-4[EBP]
mov EAX,8[EAX]
push EAX
mov ECX,offset FLAT:SINIFIM@SYM32
push ECX
push dword ptr 8[EBP]
call _d_dynamic_cast@PC32
mov EDX,EAX
add ESP,8
pop EAX
sub EAX,8[EDX]
leave
ret 4
nop
text._D5opcmp4sayi5opCmpMFC6ObjectZi ends'

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]