The issue
在low level bare-metal embedded上下文中,我想在内存中创建一个空白,在C++ struct 内,没有任何名称,以禁止用户访问这样的内存位置.
现在,我已经通过放置一个丑陋的uint32_t :96;
bit字段来实现它,它可以方便地取代三个单词,但它会引起GCC(Bitfield太大,不适合uint32_t)的警告,这是相当合法的.
虽然它工作得很好,但当你想要发布一个包含数百个警告的库时,它不是很干净...
How do I do that properly?
Why is there an issue in the first place?
我正在做的项目包括定义整个微控制器系列(STMicroelectronics STM32)不同外设的内存 struct .要做到这一点,结果是一个类,它包含多个 struct 的并集,这些 struct 定义了所有寄存器,具体取决于目标微控制器.
一个简单的外设示例如下:通用输入/输出(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;
};
};
其中所有GPIO_MAPx_YYY
是一个宏,定义为uint32_t :32
或寄存器类型(专用 struct ).
在这里,你可以看到uint32_t :192;
很好地工作,但它会触发一个警告.
What I've considered so far:
我可能会用uint32_t :32;
(这里是6)来代替它,但我有一些极端的例子,其中有uint32_t :1344;
(42)(等等).所以我不想在8k行的基础上再增加大约uint32_t :32;
行,即使 struct 生成是脚本化的.
确切的警告信息如下:
我宁愿通过简单地删除警告来解决这个问题,但是使用
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop
可能是一种解决方案...如果我找到TheRightFlag
的话.然而,正如在this thread,gcc/cp/class.c
中使用这段可悲的代码部分所指出的那样:
warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);
这告诉我们没有-Wxxx
个标志来删除这个警告...