【问题标题】:Is overflow of an unsigned bit field guaranteed to wrap-around?无符号位域的溢出是否保证回绕?
【发布时间】:2019-01-15 17:35:15
【问题描述】:

详情

reference for bit fields at cppreference 提供以下示例:

#include <iostream>
struct S {
 // three-bit unsigned field,
 // allowed values are 0...7
 unsigned int b : 3;
};
int main()
{
    S s = {7};
    ++s.b; // unsigned overflow (guaranteed wrap-around)
    std::cout << s.b << '\n'; // output: 0
}

强调保证环绕评论。

不过,WG21 CWG Issue 1816 描述了位字段值规范不明确的一些可能问题,[expr.post.incr]/1 在最新的标准草案状态中:

后缀 ++ 表达式的值是其操作数的值。 ...

如果操作数是不能表示递增值的位域,则位域的结果值是实现定义的。

但是,我不确定这是否也适用于无符号位字段的环绕。

问题

  • 是否保证无符号位域溢出?

【问题讨论】:

  • 标准似乎很清楚,cppreference 不是规范性参考...
  • 我也倾向于“不,它是实现定义的”,但想获得专家的意见。我在这里看到了一些使用(假设?)无符号位字段环绕的答案,例如用于获取无符号位字段的最大值(-1 赋值)。我想知道这些技术是否真的在使用实现定义的行为。
  • 请注意,将-1 分配给位域属于不同的问题类别,请参阅eel.is/c++draft/expr.ass#6,它更清楚。这些段落已添加到最近的标准中,因此这些问题可能比标准中的更改更早。
  • 我明白了,可以解释一下,谢谢。
  • @Holt 但是,这是真的保证(环绕)还是只是(可能是非法的)从 BF 成员的未签名中推断出来的?不过,想知道还有什么意思是完整的。

标签: c++ language-lawyer integer-overflow bit-fields


【解决方案1】:

[expr.pos]/1[expr.ass]/6 都同意(有符号或无符号)位域上的整数溢出是实现定义的。

[expr.pos]/1

[...] 如果操作数是不能表示递增值的位域,则位域的结果值是实现定义的。

[expr.ass]/6

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

我已经修复了 cppreference 页面。感谢您的关注。

【讨论】:

    猜你喜欢
    • 2010-09-14
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 2011-04-23
    相关资源
    最近更新 更多