Masalah
Dalam konteks embedded-metal tingkat rendah , saya ingin membuat ruang kosong di memori, dalam struktur C ++ dan tanpa nama, untuk melarang pengguna mengakses lokasi memori tersebut.
Saat ini, saya telah mencapainya dengan meletakkan uint32_t :96;
bitfield jelek yang akan dengan mudah menggantikan tiga kata, tetapi itu akan memunculkan peringatan dari GCC (Bitfield terlalu besar untuk muat dalam uint32_t), yang cukup sah.
Meskipun berfungsi dengan baik, itu tidak terlalu bersih ketika Anda ingin mendistribusikan perpustakaan dengan beberapa ratus peringatan itu ...
Bagaimana cara melakukannya dengan benar?
Mengapa ada masalah di tempat pertama?
Proyek yang saya kerjakan terdiri dari mendefinisikan struktur memori dari periferal yang berbeda dari seluruh jalur mikrokontroler (STMicroelectronics STM32). Untuk melakukannya, hasilnya adalah kelas yang berisi gabungan beberapa struktur yang mendefinisikan semua register, bergantung pada mikrokontroler yang ditargetkan.
Salah satu contoh sederhana untuk perangkat yang cukup sederhana adalah sebagai berikut: Input / Output Tujuan Umum (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;
};
};
Dimana semuanya GPIO_MAPx_YYY
adalah makro, didefinisikan sebagai uint32_t :32
atau tipe register (struktur khusus).
Di sini Anda melihat uint32_t :192;
mana yang berfungsi dengan baik, tetapi ini memicu peringatan.
Apa yang saya pertimbangkan sejauh ini:
Saya mungkin telah menggantinya dengan beberapa uint32_t :32;
(6 di sini), tetapi saya memiliki beberapa kasus ekstrim di mana saya memiliki uint32_t :1344;
(42) (antara lain). Jadi saya lebih suka tidak menambahkan sekitar seratus baris di atas 8k lainnya, meskipun pembuatan struktur sudah dituliskan.
Pesan peringatan yang tepat adalah seperti:
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type
(Saya suka betapa teduhnya itu).
Saya lebih suka tidak menyelesaikan ini hanya dengan menghapus peringatan, tetapi menggunakan
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop
semoga bisa menjadi solusi ... jika saya temukan TheRightFlag
. Namun, seperti yang ditunjukkan di utas ini , gcc/cp/class.c
dengan bagian kode yang menyedihkan ini:
warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);
Yang memberi tahu kita bahwa tidak ada -Wxxx
bendera untuk menghapus peringatan ini ...
char unused[12];
dan sebagainya?