Thread overview
August 11, 2013
module main;

import std.stdio;

enum y{
	a, b, c, d
}

void test(y x = y.a){
	if(x == y.a){
	}else if(x == y.b){
	}else if(x == y.c){
	}else if(x == y.d){
	}
}

int main(string[] argv){
	test();
	writeln("Hello D-World!");
	return 0;
}

Diyelim test adında böyle bir fonksiyonumuz var ve biz bu fonksiyonun aldığı parametrenin kontrolünü compile time yapmak istiyoruz. Bunu yapmanın bir yolu var mı?

Zekeriya

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

August 11, 2013

http://ddili.org/forum/thread/1161

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

August 11, 2013

Hocam biraz yanlış ifade etmişim sanırsam :)

Alıntı:

>

int test(y x = y.a){
writeln("test__");
if(x == y.a){
return 10;
}else if(x == y.b){
return 20;
}else if(x == y.c){
return 30;
}else if(x == y.d){
return 40;
}

assert(false);

}

Hocam fonksiyon tamamen compile time olmayacak sadece oradaki if kontrolü compile time olacak. Mesela burada writeln komutunu çağırabilmek de istiyorum yani. Aslında version(xxx) yapmak gibi olacak bu ama sadece bu bilgiyi fonksiyon parametresinden almak istiyorum gerekirse arkaplanda D o fonksiyonu 2 kere tanımlasın (şablonlarda öyle yapıyor diye biliyorum). Ama sanırsam böyle bir olanak yok D de.

Zekeriya

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

August 11, 2013

Alıntı (zekeriyadurmus):

>

bu fonksiyonun aldığı parametrenin kontrolünü compile time yapmak istiyoruz. Bunu yapmanın bir yolu var mı?

Bunun için en az üç yol var. Derleme zamanında yapıldığını ispatlamak için yalnızca derleme zamanında işlediğini bildiğimiz 'static assert''lerden yararlanacağım.

  1. enum olarak işaretlenmiş olan değişkenler derleme zamanında hesaplanırlar. Dolayısıyla değişkeni enum olarak işaretlemek yeterli. (Bu, D'nin hemen hemen her işlevi derleme zamanında işletebilmesinin bir sonucudur. Yani, CTFE'nin.)

enum olarak işaretlenmiş bir değişken bir hazır değerdir (manifest constant). O yüzden dereleme zamanında hesaplanır.

  1. Değişkeni 'static const' olarak işaretlemek.

Böyle bir değişkenin enum değişkenden farkı, adresinin alınabilir gerçek bir değişken olmasıdır (yani, sağ değerdir (lvalue)). enum ise daha çok C'nin makroları gibi, kullanıldığı her yere tekrar yazılan bir değer gibidir. Örneğin, aşağıdaki kodda sonuç0'ın adresi alınamaz ama sonuç1'in alınabilir.

  1. İşlev şablonu kullanmak. Şablon parametreleri derleme zamanında bilinmek zorunda olduklarından aşağıdaki örnek senin test işlevini bir şablon içinden çağırıyor.

Bunların üçü de aşağıdaki kodda var:

import std.stdio;

enum y{
   a, b, c, d
}

int test(y x = y.a){
   if(x == y.a){
       return 10;
   }else if(x == y.b){
       return 20;
   }else if(x == y.c){
       return 30;
   }else if(x == y.d){
       return 40;
   }

   assert(false);
}

int test_derleme_zamanı(y değer)(/* ... gerekiyorsa başka parametreler ... */)
{
   return test(değer);
}

int main(string[] argv){
   enum sonuç0 = test();
   static assert(sonuç0 == 10);

   static const sonuç1 = test(y.b);
   static assert(sonuç1 == 20);

   static assert(test_derleme_zamanı!(y.c)(/* ... */) == 30);

   return 0;
}

Ali

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

August 11, 2013

O olanak şablon parametreleri için var. (test_derleme_zamanı ona dayanıyar.)

İşlev parametresinde olamaz çünkü işlev parametreleri çalışma zamanı içindir. Teorik olarak, derleyici bütün programı inceyebilir ve bir parametrenin değerinin her zaman için derleme zamanında bilindiğine karar verebilir ve işlevin o bölümünü şablonmuş gibi derleyebilir. Ama derleyicinin o kararları her zaman için verebilmesi olanaksızdır. Yani, o kadar akıllı olamaz.

Ali

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