【问题标题】:Does setting a 1-bit wide bitfield to 2 mean the bitfield is set or unset?将 1 位宽的位域设置为 2 是否意味着位域已设置或未设置?
【发布时间】:2017-09-21 17:21:05
【问题描述】:

所以我有一个像这样的位域:

unsigned int foobar:1;

然后我使用此代码设置它

uint32_t code = loadCode();
structure.foobar = code & 2;

那么,如果 code 设置为 2,这是否意味着 foobar 设置为 1、0 或未定义?我使用的确切标准实际上是 C++11,而不是纯 C。

【问题讨论】:

  • 在我看来这将是一个零......想想看。 2 = 0000010。您的位域是一位。如果你与你的二进制值相比较,那个位仍然被清除。
  • 顺便说一句,这不是家庭作业,这是在代码审查中提出的,当时我们意识到我们团队中没有人知道这是否是标准定义的行为,不确定为什么会被否决。
  • @DavidHoelzer 这也是我的想法,但是 C++ 具有布尔转换的奇怪语义(即x>0 = true),这可能也适用于位域
  • 你在一段示例代码中试过了吗?
  • @Earlz 但是您的位域不是bool 类型,而是unsigned int 类型。

标签: c++ c++11 bit-manipulation bit-fields


【解决方案1】:

[expr.ass]/6:

当赋值运算符的左操作数是位域时 不能表示表达式的值,结果值为 位域是实现定义的。

同样,对于initialization

使用无法表示的值初始化位域时, 位域的结果值是实现定义的。

这是由DR 1816 添加的。作为修复标准中错误的缺陷报告,它具有事实上的追溯性。

【讨论】:

  • 我在 C++11 规范中没有看到这个,这是来自后来的规范吗? C++11中的[expr.ass]/6是“当赋值运算符的左操作数表示对T的引用时,该操作将赋值给该引用所表示的类型T的对象。”
  • 啊,所以这是在 C++14 中修复的?我猜想对于 C++11,答案是“这取决于你如何阅读规范?”
  • @cdhowie 正式 17,看起来像,但作为 DR,它应该一直返回。还要注意讨论中提出的观点,即 [conv.integral]/1 表示转换是从纯右值到纯右值,并且没有纯右值位域。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-08
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多