Vấn đề
Trong ngữ cảnh nhúng trần kim loại cấp thấp , tôi muốn tạo một khoảng trống trong bộ nhớ, trong cấu trúc C ++ và không có bất kỳ tên nào, để cấm người dùng truy cập vào vị trí bộ nhớ đó.
Ngay bây giờ, tôi đã đạt được điều đó bằng cách đặt một uint32_t :96;
bitfield xấu xí sẽ thuận tiện thay thế cho ba từ, nhưng nó sẽ đưa ra cảnh báo từ GCC (Bitfield quá lớn để vừa với uint32_t), điều này khá hợp pháp.
Mặc dù nó hoạt động tốt, nhưng nó không được sạch sẽ cho lắm khi bạn muốn phân phối một thư viện với hàng trăm cảnh báo đó ...
Làm thế nào để làm điều đó đúng cách?
Tại sao có vấn đề ngay từ đầu?
Dự án mà tôi đang thực hiện bao gồm việc xác định cấu trúc bộ nhớ của các thiết bị ngoại vi khác nhau của toàn bộ dòng vi điều khiển (STMicroelectronics STM32). Để làm như vậy, kết quả là một lớp chứa liên hợp của một số cấu trúc xác định tất cả các thanh ghi, tùy thuộc vào bộ vi điều khiển được nhắm mục tiêu.
Một ví dụ đơn giản cho một thiết bị ngoại vi khá đơn giản như sau: Một Đầu vào / Đầu ra Mục đích Chung (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;
};
};
Trong đó tất cả đều GPIO_MAPx_YYY
là macro, được định nghĩa là uint32_t :32
hoặc kiểu thanh ghi (cấu trúc chuyên dụng).
Ở đây, bạn thấy cái uint32_t :192;
nào hoạt động tốt, nhưng nó kích hoạt cảnh báo.
Những gì tôi đã xem xét cho đến nay:
Tôi có thể đã thay thế nó bằng một số uint32_t :32;
(6 ở đây), nhưng tôi có một số trường hợp cực đoan mà tôi có uint32_t :1344;
(42) (trong số những người khác). Vì vậy, tôi không muốn thêm khoảng một trăm dòng trên 8k dòng khác, mặc dù việc tạo cấu trúc đã được viết sẵn.
Thông điệp cảnh báo chính xác là một cái gì đó như:
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type
(Tôi chỉ thích nó mờ ám như thế nào).
Tôi thà không giải quyết việc này bằng cách đơn giản loại bỏ các cảnh báo, nhưng việc sử dụng
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop
có thể là một giải pháp ... nếu tôi tìm thấy TheRightFlag
. Tuy nhiên, như đã chỉ ra trong chủ đề này , gcc/cp/class.c
với phần mã đáng buồn này:
warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);
Điều này cho chúng ta biết rằng không có -Wxxx
cờ nào để xóa cảnh báo này ...
uint32_t :192;
.
:42*32
thay vì:1344
char unused[12];
và như vậy?