2016-04-11 12 views
0

Ben c bir işleve aşağıdaki geçmek istiyorum: Bu kod için daha iyi bir yoluBir uçucu değişkeni c'deki bir işleve nasıl geçiririm?

void ZeroRegister(unsigned long * _REG) 
{ 
    #define vReg (*((volatile unsigned long *)_REG)) 
    vReg = 0; 
} 

var mı: Aşağıdaki

#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC)) 

yeterince iyi iş gibi görünüyor? Yoksa kodum hatalı mı? Oluşturduğu derleyici uyarısı dışında. Başka değişkeni geçerdi olarak

+1

Bunun için neden bir '# define 'kullanırsınız; Ayrıca yazabilirsiniz * (volatile unsigned long *) _ REG = 0; ' –

+2

Ve hangi uyarı üretilir? –

+1

Bir altçizgi ve büyük harfle başlayan isimlerin 'uygulama' için ayrıldığını unutmayın - bu, bu tür isimleri kullanmamanız gerektiği anlamına gelir. –

cevap

3

Sen sadece argüman listesine volatile eleme eklemem gerekiyor, bunu aynı şekilde geçmesi:

void ZeroRegister(volatile unsigned long * _REG) 
{ 
    *_REG = 0; 
} 

herhangi önişlemci makro hile girişimi gerek yok. o uçucu belleğe bir işaretçi bekleyen böylece

+0

(Ve Jonathan Leffler'in işaret ettiği gibi, '_Xnnnn' adları uygulama için ayrılmıştır). –

4

Sen fonksiyonunu yazmak ve bu şekilde uyarıları önleyebilirsiniz (ve gerek Fonksiyonunuzda ekstra makro için var):

#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC)) 

static void ZeroRegister(volatile unsigned long *REG) 
{ 
    *REG = 0; 
} 

int main(void) 
{ 
    ZeroRegister(&GPIO_PORTF_DATA_R); 
    return 0; 
} 

Mac OS X 10.11 Açık gösterilen komut satırı ile temiz bir şekilde derler GCC 5.3.0 ile 0,4 (kaynak dosyası vui.c olan): function parametresinden volatile belirtilmemesi

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \ 
>  -Wold-style-definition -Werror -c vui.c 
$ 

uyarılar (hat numaraları ve eşleşmiyor değişken adlarına yol açar yukarıdaki kod; onlar kod önceki bir sürümü) elde edildi: Derleme Yukarıdaki kod uygulaması için ayrılmış bir ad kullanarak önler

… 
vui.c: In function ‘main’: 
vui.c:11:18: error: passing argument 1 of ‘ZeroRegister’ discards ‘volatile’ qualifier from pointer target type [-Werror=discarded-qualifiers] 
    ZeroRegister(&GPIO_PORTF_DATA_R); 
       ^
vui.c:3:6: note: expected ‘long unsigned int *’ but argument is of type ‘volatile long unsigned int *’ 
void ZeroRegister(unsigned long * _REG) 

Not söyledi. Bir altçizgi ile başlayan tüm isimler ve büyük harf (ya da başka bir alt çizgi) uygulama için ayrılmıştır. ISO/IEC 9899 Bkz: 2011 §7.1.3 Ayrılmış tanımlayıcılar:

  • bir alt çizgi ile başlar ve bir büyük harf ya da başka birini altını Tüm isimleri daima herhangi bir kullanım için ayrılmıştır.
  • Alt çizgi ile başlayan tüm tanımlayıcılar, her zaman olağan ve etiket adı boşluklarında dosya kapsamı olan tanımlayıcılar olarak kullanım için ayrılır.
+0

Teşekkürler, bu harika bir çözüm gibi görünüyor.Uçucu, adresi değil, _REG içeriğine atıfta bulunur - değil mi? statik boşluk ZeroRegister (uçucu imzasız uzun * REG) { * REG = 0; } –

+0

Evet, bu "uçucu", işaret edilen nesnenin "uçucu" olduğunu söylüyor. İşaretçi kendini uçucu ise, gösterim ZeroRegister (işaretsiz uzun * uçucu REG) 'olacaktır. Bu, const’e benzer. –

+0

Açıklamalarda 'code' etrafında geri sayılar kullandığınızı unutmayın. –

İlgili konular