Picproje Elektronik Sitesi

PROGRAMLAMA DİLLERİ => C/C++ => Konuyu başlatan: mr.engineer - 05 Nisan 2021, 12:40:38

Başlık: Glvalue, Rvalue Lvalue
Gönderen: mr.engineer - 05 Nisan 2021, 12:40:38
Merhaba, C++ da value category diye  lvalue, xvalue, prvalue, glvalue terimlerini içeren bir konu var. Anladığım kadarıyla lvalue memory'de yer kaplamalı. PR value ise yer kaplamamalı sabit bir değer belirtmeli. Yani sabit bir sayı veya int foo() şeklinde bir fonksiyon. Anlamadığım yerler ise;

1. ++a lvalue oluyorken, a++ nasıl pr value oluyor?

2. a.*mp, burada a rvalue ve mp pointer to data member ise lvalue oluyormuş. Bu nasıl oluyor. a burada nasıl rvalue olabiliyor? Bunun örneği nedir? 

3. xvalue tam olarak nedir? Bir yerde rvalue reference'lar için kullnılıyor yazmış başka bir yerde farklı bir sey yazmış.



C++ 'de yeni olan birinin bunları anlaması gerekiyor mu? Her şeyi bilmediğimden anlayamadım gibi geliyor.
Başlık: Ynt: Glvalue, Rvalue Lvalue
Gönderen: Tagli - 05 Nisan 2021, 12:58:51
Ben de yeni yeni C++ öğrenip kullanmaya başladım. Bu konular benim de kafama çok girmedi. Ama başlangıçta her şeyi yalayıp yutmak gerekmiyor. C++ dipsiz kuyu gibi zaten. Yerinde de durmuyor, son yıllarda zırt pırt yeni standartlar çıkıyor. Ben STM32 için C++17 kullanıyorum ama tüm özelliklerini bilip kullandığımı söyleyemem tabi.

rvalue kabaca geçici değer demek, ya da ben o kadarını anlayabildim. rvalue olan bir şeyin yakın zamanda (mesela o komutun çalışmasının ardından) ömrü sona erecek demektir. Bunlar genelde C++11 ile birlikte gelen move işlemleri ile ilgili. Uygulanabildiği yerlerde ciddi performans artışı sağlıyor. Move işlemlerinin ana fikri, zaten yok olacak bir nesnenin heap üzerinde saklanan verilerini çalmak. Böylece tekrardan yer ayırma ve kopyalama işlemlerinden kaçınılmış oluyor.
Başlık: Ynt: Glvalue, Rvalue Lvalue
Gönderen: brandice5 - 05 Nisan 2021, 13:17:51
Bu konular @Tagli'nın da dediği gibi performansla ilgili konular. Başlangıç seviyesi için çok derine inmek gerekir mi? tartışılır.

Mesela C++11 ile std::move getirildi. Bunu şöyle düşünebilirsin, elinde iki tane bardak var, biri dolu biri boş.
Sen dolu bardaktaki suyu boş bardağa aktarmak istiyorsun. std::move dan önce yapılan işlem, dolu bardaktaki suyu boş bardağa boşaltmaktı, yani kopyalama. Eğer bardağın baya büyükse bu dökme yani kopyalama işlemi ekstra zaman alıyordu yani performans olumsuz etkileniyordu.

İşte std::move ile bu bardaktan bardağa boşaltma (kopyalama) işlemi ortadan kaldırıldı. Şu an yapılan işlem boş bardağı yok edip, yerine direkt dolu bardağı koymak (move).
Yani kopyalama ile zaman kaybetmek yok, ve suyun miktarından bağımsız (isterse bir sürahi olsun).
Başlık: Ynt: Glvalue, Rvalue Lvalue
Gönderen: volkanunal - 05 Nisan 2021, 13:40:34
1.sorununuz cevabı aslında C++ ile ilgili değil, POD (Pre-Post Increment) konusu standartlarda belirtilmiş.

The pre-increment should act as if the object was incremented before the expression and be usable in this expression as if that happened. Thus the C++ standards comitee decided it can also be used as an l-value.

The post-increment should increment the POD object and return a copy for use in the expression (See n2521 Section 5.2.6). As a copy is not actually a variable making it an l-value does not make any sense.



Örnek vermek gerekirse.
a++ = 2;

Yukarda bulunan kod hata olarak karşımıza çıkacaktır. Çünkü ifadenin bir kopyası döndürülmekte.

++a = 2;

Yukarda bulunan kod ise derlenecektir. Çünkü ifadenin this pointeri(yani kendisi) dönmekte.

Tabi değer kategori konusunda C ve C++ farklılıklar bulunmakta.


Bende C++ öğrenmeye çalışıyorum, şurada notlarımı paylaşıyorum (Ders 3 içerisinde bu konuda detaylı notları paylaştım.)
https://engineeringvolkan.wordpress.com/2021/02/07/c-kursu-notlarim/



Başlık: Ynt: Glvalue, Rvalue Lvalue
Gönderen: mr.engineer - 05 Nisan 2021, 14:17:26
Right left value konusu C'de de vardı ama pek önemi yoktu ya da ben öyle zannediyordum fakat C++'da işler farklıymış:)
Teşekkürler cevaplar için.
@volkanunal notlar güzel olmuş emeğine sağlık.
Başlık: Ynt: Glvalue, Rvalue Lvalue
Gönderen: mr.engineer - 05 Nisan 2021, 14:27:44
Alıntı yapılan: volkanunal - 05 Nisan 2021, 13:40:341.sorununuz cevabı aslında C++ ile ilgili değil, POD (Pre-Post Increment) konusu standartlarda belirtilmiş.

The pre-increment should act as if the object was incremented before the expression and be usable in this expression as if that happened. Thus the C++ standards comitee decided it can also be used as an l-value.

The post-increment should increment the POD object and return a copy for use in the expression (See n2521 Section 5.2.6). As a copy is not actually a variable making it an l-value does not make any sense.



Örnek vermek gerekirse.
a++ = 2;

Yukarda bulunan kod hata olarak karşımıza çıkacaktır. Çünkü ifadenin bir kopyası döndürülmekte.

++a = 2;

Yukarda bulunan kod ise derlenecektir. Çünkü ifadenin this pointeri(yani kendisi) dönmekte.


Burası ilginç. C'de ikisi de derlenmiyor:) İkisi de right value galiba. Dediğin gibi standarda bakmak lazımmış. Ben bir mantık göremedim ama C++ çalışabilmesinin de sebebi vardır heralde.
Başlık: Ynt: Glvalue, Rvalue Lvalue
Gönderen: Tagli - 05 Nisan 2021, 16:51:46
a++ rvalue oluyor çünkü ++ operatörü uygulanmadan önceki hali o komutta (expression?) kullanılıyor ve sonra yok ediliyor. a'nın sadece ++ uygulandıktan sonraki yeni hali hayatta kalıyor.