我怎样才能安全地将更宽的整数类型转换为位域? [英] How can I safely convert a wider integer type to a bitfield?
问题描述
#include< stdint.h>
struct MaskAndCount {
uint64_t占用:56;
uint8_t numOccupied:8;
};
int main(){
int count = 7;
MaskAndCount foo;
foo.occupied& =〜(1L<< count);
$ b $ p
$ b 如果我用 -Wconversion 编译这段代码, code>,那么我会得到以下错误。
g ++ -Wconversion Main.cc
Main。 cc:在函数'int main()'中:
Main.cc:11:18:警告:从'long unsigned int'转换为'long unsigned int:56'可能会改变它的值[-Wconversion]
foo.occupied& =〜(1L << count);
这似乎是一个合理的问题,但我期望的行为恰恰是截断所有高位
$ b 我的问题是双重的。
- 转换成书面文件有理想的效果,截断右边的值的高位?
- 有没有办法使本地警告静音或用不同的语法表达相同的行为它不会触发警告?
请注意,我尝试了下面的静态转换,它根本不编译。
static_cast< uint64_t:56>(〜(1L<< count))
/ pre>
解决方案最高位(如果设置)将被忽略。
您可以通过在作业之前自行删除顶部位来避免警告:
int count = 7;
MaskAndCount foo = {};
//截掉前8位
foo.occupied& =〜(1 << + count)& 0x00FFFFFFFFFFFFFFUL;
编辑:原来这不适用于 | =
(不知道为什么)。但可以通过避免 | =
并使用正常赋值来修复:
foo.occupied =(foo.occupied&〜(1UL<< count))& 0x00FFFFFFFFFFFFFFUL;
foo.occupied =(foo.occupied |〜(1UL << count))& 0x00FFFFFFFFFFFFFFUL;
Consider the following code.
#include <stdint.h>
struct MaskAndCount{
uint64_t occupied : 56;
uint8_t numOccupied : 8;
};
int main(){
int count = 7;
MaskAndCount foo;
foo.occupied &= ~(1L << count);
}
If I compile this code with -Wconversion
, then I will get the following error.
g++ -Wconversion Main.cc
Main.cc: In function ‘int main()’:
Main.cc:11:18: warning: conversion to ‘long unsigned int:56’ from ‘long unsigned int’ may alter its value [-Wconversion]
foo.occupied &= ~(1L << count);
This seems to be a legitimate concern, but my desired behavior is precisely to truncate all the higher bits of the value on the right.
My question is twofold.
- Will the conversion as written have the desired effect of truncating the higher bits of the value on the right?
- Is there is a way to either silence the warning locally or expressing the same behavior with a different syntax which does not trigger the warning?
Note that I have tried the following static cast, which does not compile at all.
static_cast<uint64_t:56>(~(1L << count))
解决方案 As is the top bits (if set) will get ignored.
You can avoid the warning by removing the top bits yourself before the assignment:
int count = 7;
MaskAndCount foo = {};
// chop off the top 8 bits
foo.occupied &= ~(1 << count) & 0x00FFFFFFFFFFFFFFUL;
EDIT: Turns out this will not work for |=
(not sure why). But that can be fixed by avoiding |=
and using normal assignment:
foo.occupied = (foo.occupied & ~(1UL << count)) & 0x00FFFFFFFFFFFFFFUL;
foo.occupied = (foo.occupied | ~(1UL << count)) & 0x00FFFFFFFFFFFFFFUL;
这篇关于我怎样才能安全地将更宽的整数类型转换为位域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!