Sorun
Bir de düşük düzeyde çıplak metal gömülü bağlamda, bir erişim, bellek konumu için kullanıcı yasaklamış, C ++ yapı içinde ve herhangi bir isim vermeden, bellek boş bir alan yaratmak istiyoruz.
Şu anda, bunu uint32_t :96;
üç sözcüğün yerini alabilecek çirkin bir bitfield koyarak başardım , ancak bu oldukça meşru olan GCC'den (Bitfield uint32_t'ye sığmayacak kadar büyük) bir uyarı getirecek.
İyi çalışsa da, bu uyarıların birkaç yüzünü içeren bir kitaplığı dağıtmak istediğinizde çok temiz değil ...
Bunu nasıl düzgün bir şekilde yaparım?
İlk etapta neden bir sorun var?
Üzerinde çalıştığım proje, tüm bir mikrodenetleyici hattının (STMicroelectronics STM32) farklı çevre birimlerinin bellek yapısını tanımlamaktan ibarettir. Bunu yapmak için, sonuç, hedeflenen mikro denetleyiciye bağlı olarak tüm kayıtları tanımlayan birkaç yapının bir birleşimini içeren bir sınıftır.
Oldukça basit bir çevre birimi için basit bir örnek şudur: Genel Amaçlı Giriş / Çıkış (GPIO)
union
{
struct
{
GPIO_MAP0_MODER;
GPIO_MAP0_OTYPER;
GPIO_MAP0_OSPEEDR;
GPIO_MAP0_PUPDR;
GPIO_MAP0_IDR;
GPIO_MAP0_ODR;
GPIO_MAP0_BSRR;
GPIO_MAP0_LCKR;
GPIO_MAP0_AFR;
GPIO_MAP0_BRR;
GPIO_MAP0_ASCR;
};
struct
{
GPIO_MAP1_CRL;
GPIO_MAP1_CRH;
GPIO_MAP1_IDR;
GPIO_MAP1_ODR;
GPIO_MAP1_BSRR;
GPIO_MAP1_BRR;
GPIO_MAP1_LCKR;
uint32_t :32;
GPIO_MAP1_AFRL;
GPIO_MAP1_AFRH;
uint32_t :64;
};
struct
{
uint32_t :192;
GPIO_MAP2_BSRRL;
GPIO_MAP2_BSRRH;
uint32_t :160;
};
};
Hepsi GPIO_MAPx_YYY
bir makrodur, ya uint32_t :32
kayıt tipi olarak tanımlanır (özel bir yapı).
Burada uint32_t :192;
hangisinin iyi çalıştığını görüyorsunuz , ancak bir uyarıyı tetikliyor.
Şimdiye kadar düşündüklerim:
Birkaç tane ile değiştirmiş olabilirim uint32_t :32;
(burada 6), ancak sahip olduğum bazı aşırı durumlar var uint32_t :1344;
(42) (diğerleri arasında). Bu nedenle, yapı oluşturma komut dosyası yazılmış olsa bile, 8k diğerinin üzerine yaklaşık yüz satır eklememeyi tercih ederim.
Tam uyarı mesajı şöyle bir şeydir:
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type
(Ne kadar gölgeli olduğunu seviyorum).
Daha doğrusu olurdu değil sadece uyarı kaldırarak bunu çözmek, ancak kullanımı
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop
bir çözüm olabilir ... bulursam TheRightFlag
. Ancak, bu başlıkta da belirtildiği gibi , gcc/cp/class.c
bu üzücü kod bölümü ile:
warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);
Bu da bize -Wxxx
bu uyarıyı kaldıracak bayrak olmadığını söylüyor ...
char unused[12];
vesaire?