分配给位字段时GCC转换的子项警告
我试图解决几乎完全相同的问题,除了没有一个解决方案似乎有效。与相关问题一样,gcc版本似乎没有帮助,gccs 10.1、9.1、8.2、8.1、7.1、6.1、5.1和4.9.1都失败了分配给位字段时GCC转换的子项警告,c,gcc,compiler-warnings,suppress-warnings,C,Gcc,Compiler Warnings,Suppress Warnings,我试图解决几乎完全相同的问题,除了没有一个解决方案似乎有效。与相关问题一样,gcc版本似乎没有帮助,gccs 10.1、9.1、8.2、8.1、7.1、6.1、5.1和4.9.1都失败了 typedef unsigned int uint; struct foo { uint a:8; uint b:24; }; void bar(struct foo num, uint x) { num.b = (5U << 1) | (1 & 1); num.b = ((
typedef unsigned int uint;
struct foo { uint a:8; uint b:24; };
void bar(struct foo num, uint x) {
num.b = (5U << 1) | (1 & 1);
num.b = ((uint)(((5U << 1) | (uint)((uint) x & 1))) & 0xffffffU);
num.a = (unsigned char)x;
}
typedef无符号整数uint;
结构foo{uint a:8;uint b:24;};
空栏(结构foo num,uint x){
num.b=(5U如果一天后我没有任何答案可以接受,我将从评论中总结发现
- @Artyer发现将变量转换为布尔值可以解决问题。这可以解决战术问题,但不能解决更一般的问题(例如
z&0xf
)
- 在研究上述解决方案时,我发现将表达式的“常量”端存储到变量中通常可以解决问题
unsigned int z = 5U;
num->b = (z << 1) | (x & 1);
无符号整数z=5U;
数值->b=(z)你似乎在自找麻烦。我在GCC 8.3.1中很难再现这一点:使用-Wall-Wextra-pedantic
编译时没有发出你提出的转换警告。原因显然是,该警告不包括在任何警告组中。我仅在我明确要求d-Wconversion
或-Werror=conversion
。因此不要这样做。警告未包含在上述任何组中是一个很好的迹象,表明它仅用于特殊目的。@ryker,1
具有类型int
,而1u
具有类型未签名的int
,但这实际上不是m在OP的代码中使用任何差异。num->b=(5U b=x&1?10:11
也可以,但这显然不适用于所有情况。(版本)在GCC的-Wconversion
实现中,您很可能会遇到错误。如果它在最新的GCC中重现,您可以在(如果没有,则表示已修复)。目前,您唯一的选择是通过pragmas或Makefile禁用此特定文件的-Wconversion
,从而解决此问题。
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
num.b = (5U << 1) | (x & 1U);
#pragma GCC diagnostic pop
uint z = 5U;
num.b = (5U << 1) | (1 & 1); //OK
num.b = ((z << 1) | (x & 1)) & 0xffffffU; //OK
num.b = ((5U << 1) | (x & 1)) & 0xffffffU; //BAD
num->b = (5U << 1) | (_Bool)(x & 1);
num->b = (5U << 1) | !!(x & 1);
unsigned int z = 5U;
num->b = (z << 1) | (x & 1);