volatile ve const bir arada kullanımı

Başlatan ErsinErce, 07 Mart 2014, 21:55:00

ErsinErce

const olarak oluşturduğum bir structure mevcut, bu structure içeriğinde pointer larım var ve bu pointer'a ram üzerinden erişim sağlamaya çalışıyorum.

programı hatasız derledim fakat const struct olarak oluşturduğum ram üzerinden erişebilmek için volatile const struct yazarak erişim sağlayabiliyorum
çok dikkatimi çekmeyen yazım sırası bu sefer çok önem taşıdı ve yanlış yapmadığımdan emin olmak istiyorum.

yazdığım kodlar aşağıdakiyle benzer durumda
typedef struct Settings_t{
    uint8_t type;
    uint8_t *value;
    const struct Settings_t *structure;
}Settings;

const Settings x;

volatile const Settings *p;

p = &x;


internette birkaç örnekte aşağıdaki yazım şekliyle karşılaştım ve bu şekilde deneme yaptığımda hatasız derlenen program hata vermeye (pointer mismatch) başladı.

volatile Settings * const p;


Konuyu biraz merak edip araştırdım ama pek birşey bulamadım,
bu konuda tecrübesi olan biri varsa sıralamanın önemi ve ne şekilde olması gerektiğini açıklayabilir mi?

elektronart

enteresan bir durum, constantla tanımladığınınız bir verinin değişmemesi beklenir, en azından derleyici böyle olacağını düşünür.
Volatile ile tanımladığını pointerdan const özelliğini kaldırdıp denediniz mi?
Açık Elektronik

yamak

#2
Hocam bir pointer ı
const char* ptr;

şeklinde tanımlarsanız pointer ın işaret ettiği yerdeki veriyi değiştiremezsiniz ama ptr adresini değiştirebilirsiniz.
*ptr=5;//Kullanılamaz
ptr=(char*)0x08000040;//Kullanılabilir

Fakat;
"char* const ptr"

şeklinde tanımlarsanız ptr adresini değiştiremezsiniz ama ptr'nin işaret ettiği yerdeki veriyi değiştirebilirsiniz
ptr=(char*)0x08000040; // Kullanılamaz
*ptr=5;//Kullanılabilir

ErsinErce

Alıntı yapılan: elektronart - 07 Mart 2014, 22:25:01
enteresan bir durum, constantla tanımladığınınız bir verinin değişmemesi beklenir, en azından derleyici böyle olacağını düşünür.
Volatile ile tanımladığını pointerdan const özelliğini kaldırdıp denediniz mi?

Olayı tam ifade etmek gerekirse

ram de x adresi mevcut ben bu x adresine erişmek için const olarak tanımladığım bir yapıdan çağırıyorum.

x'in ramdeki adresi sabit yani.

sonra const olarak tanımladığım yapıdan x'in adresini öğrenip x'e değer atıyorum.

yaptığım olay bu

bir değişkeni hem const hem volatile olarak kullanmıyorum yani.

volatile olan bir değişkenin adresini const yapıdan çekerek erişiyorum

sadece sıralama farkının neler yapabileceğine şahit oldum. olayı biraz kavradım ama dahası var mı ya da başka hangi örnekler karşımıza çıkabilir bunu öğrenmek istiyorum.

@yamak

mesela aşağıdaki kod içinde aynı şey geçerli mi?

aşağıdaki yapıyı const yapı içine kullanırsam nasıl bir sonuçla karşılaşırım?

volatile uint16_t *value;
uint16_t *volatile value;

yamak

volatile'ın bu şekilde yerdeğiştirmesi ne gibi bir sonuç getirir bilmiyorum ama.Bence ifadelerin önüne const koyarsanız ikisi içinde aynı şey olur.


ErsinErce

#6
artık iyice saçmalamaya başladım galiba, fonksiyon üzerinden erişim yaptırmaya kalktığımda erişemiyorum =/

normalde yazdığım kodlar bayağı uzun iyice anlaşılmaz olmasın diye ufak bir örnek koydum

flash ve ram yapım aşağıdaki gibi, kodlar fonksiyonlarda benzer, nerede saçmalıyorum rica etsem gösterebilir misiniz?


Not sarı renk stringler, yeşiller sayı, maviler pointer

typedef struct{
    const char * x;
    const char y;
    const char * const t[2]
    volatile char * const k[3]
    const char z[3] 
}strct_temp;

volatile char vc[3];

const char str1[] = {"abcdef"};
const char str2[] = {"ghijkl"};
const char str3[] = {"zxcz"};

const strct_temp strct = { &str1, 0, { &str2, &str3 }, { &vc[0], &vc[1], &vc[2] }, { 1, 1, 1 } };

const strct_temp *volatile r;
const char *volatile h;

void func(const char *volatile text){
    r = &strct;
    *text = r->t[1];
}

void main(void){
    func( &h);
}


bu kodda
*text = r->t[1];
satırını derleyemiyor pointer'a sayı atamaya çalışıyorsun diyor =S

compiler da mı yoksa sorun bende mi?

yamak

Hocam ne yapmak istediğinizi bilmiyorum ama;Şu şekilde olması gerekmez mii?
*text=r->t[1];
ya da
text=r->t;

çünkü r->t[1] bi adres değil char türünden bir değer belirtir.

ErsinErce

#8
o noktada yıldız var yanlış eklemişim şuan ki tam yazdığıma benzer şekilde

text local değişken zaten dışarı eriştirmiyor. point etmek şart

olayı menü sistemi gibi düşünebilirsiniz. menünüzde hem sabitleriniz(string, int vs) var hem değişkenleriniz
seçenekleri ilk başta sabit yapılar haline getirip, yapıya bir pointer atayarak ilgili kısma direk erişim sağlayabiliyorsunuz.

---

r->t[1] 'in adresi işaret etmesi gerekmiyor mu?
*(r->t[1]) de de stringin kendisi gelmesi lazım

stringin adresini dışarıya aktarmam gerekiyor.

sonra o adrese pointerla erişip içeriğini yazabiliriz.

yamak

#9
Hocam
r->t[0]
derseniz dediğiniz doğru olur.Ama
derleyici *(r->t[0]) şeklinde kullanıma hata verebilir o yüzden tip dönüşümü yapmanız gerekebilir.
*(char*)(r->t[0]) şeklinde.

ErsinErce

r->t[0] da str 2 nin adresi r->t[1] de str3'ün adresi var

yamak

#11
Hocam haklısınız ben yanlış görmüşüm.
O zaman text=r->t[1]; şeklinde olması lazım. :)

Hocam fonksiyon verilen parametrenin adresini değiştirmek istediğiniz için fonksiyonunu aşağıdaki gibi olması gerekir

void func(char ** volatile text){
    r = &strct;
    *text = r->t[1];
}
Bu şekilde çalışması lazım artık :)

ErsinErce

#12
Teşekkür ederim @yamak girişteki çift yıldız işi çözdü =)

warning olarak aşağıda yazanı diyordu
illegal conversion between pointer types
pointer to volatile pointer to const unsigned char -> volatile pointer to pointer to const unsigned char


volatile ı ortaya alınca sorun kalmadı

void func(char * volatile * text){
    r = &strct;
    *text = r->t[1];
}


yalnız bu structure konusunda hâla şüphelerim var.