从 int 中剥离位时,编译器会警告一个转换,但不警告其他转换.有解决方法吗?
When stripping bits out of an int, the compiler warns about one conversion but not others. Is there a workaround?
在下面的代码中,我的编译器抱怨其中一个转换,而不是其他转换。
unsigned ARGB;
unsigned char a( ARGB >> 24 );
unsigned char r( ( ARGB & 0xFF0000 ) >> 16 ); // warning!
unsigned char g( ( ARGB & 0xFF00 ) >> 8 );
unsigned char b( ARGB & 0xFF );
编译器报告"警告 C4244:'正在初始化':从'int'转换为'char',可能丢失数据"......但仅适用于第二次转换。
我想我明白它为什么要这样做了。a
和b
显然是只留下 8 个有效位的单个操作的结果,在g
的情况下,按位&
产生 16 个有效位(可以存储在short
中而不会丢失(,然后结果向右移动,只留下 8 位。但是,相比之下,对r
执行的按位&
操作会留下一个具有 24 个有效位的中间值,如果要将其存储在某处,则需要int
。我猜编译器将移位视为一个单独的进程,作用于整数,这就是为什么它警告可能丢失数据的原因。
由于我们将(几乎所有(警告视为错误,因此我需要解决此问题。显然,我可以使用static_cast
来明确记录我想要的内容,但这(在我看来(是一个丑陋的工具,并且表明代码可以写得更好。
有谁知道一种漂亮、整洁、符合标准且可移植的代码形式,可以执行所需的数据转换?
由于可移植性问题,我宁愿不依赖位域。
当交换移位和 AND 的顺序时,警告消失,因此:
unsigned char r( ( ARGB >> 16) & 0xFF );
正如另一个答案中提到的,更改操作可能会有所帮助,但它还有另一个优点:一致性(如果您考虑删除过时的括号,那么,第二个(:
unsigned char a( ARGB >> 24 );
unsigned char r( ARGB >> 16 & 0xffU );
unsigned char g( ARGB >> 8 & 0xffU ); // same value as above
unsigned char b( ARGB & 0xffU ); // -- " --
(您也可以在第一行添加掩码,并将 0 移动到最后一行,并希望编译器再次优化它们 - 实际上,它应该对所有掩码都这样做,因为您无论如何都分配给 8 位大小的变量......
现在回到警告(你显然仍然没有摆脱(:显式强制转换现在应该真正强制编译器删除它:
unsigned char x(static_cast<unsigned char>(argb >> y & 0xffU));
相关文章:
- 将无符号转换为复杂<int>原因符号转换警告
- 为什么在 c++ 中索引字符串会发出隐式转换警告?
- C++:禁用隐式转换警告
- 意外 (IMO) 常量转换警告
- C++:禁用 CMake 中的旧样式转换警告
- 键入从 DWORD 到 64 位指针的强制转换警告
- 隐式转换警告 int 到 int-looklike
- 移植到 64 位时如何避免size_t int 强制转换警告?
- 构造函数中的 C4267 转换警告 - 无法修复过载?
- 如何修复隐式转换警告?
- 为什么在一种情况下,我会收到带有字符串文字的已弃用转换警告,而在另一种情况下却没有?
- 在 C++ 中修复类型转换警告的最佳方法
- 为什么仅在列表初始化的情况下才会出现狭窄的转换警告
- -在无符号字符上使用运算符 <<= 时的转换警告
- 如何在gcc或clang中启用从int到int64_t的转换警告
- 如何禁用缩小转换警告
- 使用复合赋值运算符解决转换警告
- gcc 奇怪的转换警告(<B>从"int"转换为"A::count_type {aka short unsigned int}"可能会改变其值)
- 强制缩小转换警告
- 旧风格使用sys/select.h宏强制转换警告