Merhaba,
Unutmadan yazmalıyım; bugün Zoom ile yaptığımız D buluşmasında şu @safe ve @trusted mevzuları konuşuldu. Devam etmeden önce lütfen bakınız:
https://dlang.org/spec/function.html#function-safety
Ali hocam ayrıntılı bilgi verecektir. Ben bu konuyu önemsediğim için, toplantıda yazılan bir kod üzerinden 2 denemeyi buraya naklediyorum. Aslında ilkini (yani tersini) denememiştik, koddan sonra açıklayacağım:
import std.stdio;
@safe:
void küyükSayı (ref ubyte k) {
auto p = () @trusted {
return cast(uint*)&k;
} ();
*p = 300;
}
// *imla hatası kolaylık için yapıldı: kü*ük
void büyükSayı (ref uint b) {
auto p = () @trusted {
return cast(ubyte*)&b;
} ();
++(*p);
}
void main()
{
uint i = ubyte.max - 1; // uint içinde 254 var,
i.büyükSayı; // bu bir büyük sayı...
assert(i == ubyte.max); // ama 255 oldu: NORMAL
i.büyükSayı; // şimdi 256 olmalıydı
assert(i == ubyte.min); // ama 0 oldu: NASIL?
ubyte n; // 0 ile ilklenmiş bir uybte
n.küyükSayı; // ubyte.max üstünde bir değer
n.writeln; // atadık ama bende 44 çıktı!
} /* ÇIKTISI:
44
* Evet bir çift sayı ve bu bende çıktı! Muhtemelen
* sizde farklıydı ama 300 olmalıydı. İşler karıştı
* çünkü güvenilir (trusted) yazınca D'yi kandırdı!
* Gökten 300 elma düşmüş...:)
*/
Ali hocam, küyük/büyük işlevlerine benzeyen bir foo() yazmıştı ve değerleri aynı şekilde dönüştürüp 42'ye eşitlemişti. Ben ise işaretsiz (uint) tahsis ederek 300 değerini almasını istedim. Tek fark int yerine uint ve 42 yerine 300 o kadar!
Ama 44 gibi absürt bir sonuç çıktı çünkü ayıp bir iş yaptık, sağ gösterip (trusted) sol vurduk (left stranded) yoksa yine her şey normal...
İlk örneği ise denemedik! Bu sefer bellekte ubyte'a göre ferah bir alan (uint) verdim ve cast edilen ile maniple edileni yine işaretsiz olmasına çalıştım. Bu yüzden 255'den sonra sanki büyük sayı değilmiş gibi 0'a geri döndü. Yani ubyte gibi davrandı ama bu sonuç sizde farklı çıkabileceği gibi yine güvenilir değildir.
(Unutmadan son bir not daha): -O ile derlemeyi denemelisiniz, o zaman farklı sonuç alıyorsunuz.
Başarılar...