January 05, 2013

Alıntı:

>

dmd 2.061'e geçenlerin karşılaştıkları bir durum, bazı kodlarının artık derlenemiyor olması. Bu rvalue'lar ve ref parametrelerle ilgili bir durum.

Yeni sürümü görünce bende hemen güncelledim ve her yerden hata verdiğini görünce (kullandığım kütüphaneler dahil :)) tekrar 2.060'a geri döndüm.

Yeni eklenen özelliğe gelince açıkçası böyle olması daha mantıklı olmuş. Madem nesne yok olacaksa değişiklik yapmanın bir anlamı yok. Ama d diline label address alma da gelmiş olsaydı iyi olurdu. Bu tarz bir şeyi nasıl bildirebiliyoruz?

Zekeriya

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

January 04, 2013

dmd 2.061'e geçenlerin karşılaştıkları bir durum, bazı kodlarının artık derlenemiyor olması. Bu rvalue'lar ve ref parametrelerle ilgili bir durum.

struct Yapı
{
   int i;

   void değiştir()
   {
       ++i;
   }
}

/* foo() parametresini referans olarak alıyor. Herhalde onda değişiklik
* yapacak. Bunun anlamlı olabilmesi için o parametrenin bir sol-değer
* (lvalue) olması gerekir. Sağ-değer (rvalue) olsa, yani örneğin geçici bir
* değişken olsa, yaptığı değişiklik kaybedilirdi.
*
* Not: C++ rvalue'ların const olmayar referans olarak gönderilmesine izin
* vermez.
*/
void foo(ref Yapı nesne)
{
   nesne.değiştir();  /* <-- 'nesne' sağ-değer ise şüpheli bir durumdur çünkü
                       *     bu değişiklik geçici bir nesnede yapılıyor
                       *     demektir ve dolayısıyla kaybedilecektir.
                       */
}

/* Bu işlev bir nesne oluşturur ve döndürür. Döndürdüğü sonuç bir
* sağ-değerdir; şu kod yasal değildir:
*
*    nesneDöndür() = Yapı(42);  // <-- DERLEME HATASI: Sağ-değere atamaya
                                //                     çalışıyor.
*/
Yapı nesneDöndür()
{
   return Yapı(2);
}

void main()
{
   /* Bu her zaman için yasaldı çünkü foo()'ya başlı başına bir nesne (yani
    * lvalue) veriliyor. */
   auto nesne = Yapı(0);
   foo(nesne);
   assert(nesne.i == 1);

   /* dmd 2.060 ve önceki sürümleri hatalı davranıyordu ve aşağıdakilerden
    * birisine izin veriyordu. (Hangisi olduğunu hatırlamıyorum. :))
    *
    * dmd 2.061 bu hatayı giderdi: Artık ikisi de derleme hatasıdır.
    */
   foo(Yapı(1));         // <-- DERLEME HATASI
   foo(nesneDöndür());   // <-- DERLEME HATASI
}

Tam çözümün ne olduğundan veya ne olacağından emin değilim. Söylendiğine göre, şimdiye kadar şablonlarla kullanılan 'auto ref' normal işlevlere de genişletilecekmiş ve bu konuda yardımcı olacakmış.

Şimdilik benim bildiğim tek çözüm, foo()'yu şablona dönüştürmek ve böylece parametresini 'auto ref' olarak işaretleyebilmek:

void foo(T)(auto ref T nesne)
{
   /* ... */
}

Öyle yapınca derleyici lvalue ve rvalue durumuna göre iki işlev üretiyor. lvalue için 'ref' yazılmış gibi derliyor, rvalue için de 'ref' yazılmamış gibi.

Derleyicinin ürettiği işlevler şunun gibi oluyor:

import std.stdio;
// ...
void foo(ref Yapı nesne)
{
   writeln("Sol-değer için");
   nesne.değiştir();
}

void foo(Yapı nesne)
{
   writeln("Sağ-değer için");
   nesne.değiştir();
}

Yukarıdaki o iki işlevi kendimiz elle de öyle yazabilirdik. (Ve zaten ben de öyle yaptım! :)) main içinde bir lvalue iki de rvalue için çağrıldığından çıktı şöyle oluyor:

'Sol-değer için
Sağ-değer için
Sağ-değer için'

Ali

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