使用std :: size_t和std :: bitset进行位操作的输出差异

时间:2017-09-29 18:12:29

标签: c++11

拥有以下代码:

#include <iostream>
#include <bitset>
#include <limits>
#include <limits.h>
using namespace std;

constexpr std::size_t maxBits = CHAR_BIT * sizeof(std::size_t);

int main() {
    std::size_t value =47;
    unsigned int begin=0;
    unsigned int end=32;

    //std::size_t allBitsSet(std::numeric_limits<std::size_t>::max());
    std::bitset<maxBits> allBitsSet(std::numeric_limits<std::size_t>::max());
    //std::size_t mask((allBitsSet >> (maxBits - end)) ^(allBitsSet >> (maxBits - begin)));
    std::bitset<maxBits> mask = (allBitsSet >> (maxBits - end)) ^(allBitsSet >> (maxBits - begin));

    //std::size_t bitsetValue(value);
    std::bitset<maxBits> bitsetValue(value);

    auto maskedValue = bitsetValue & mask;
    auto result = maskedValue >> begin;

    //std::cout << static_cast<std::size_t>(result) << std::endl;
    std::cout << static_cast<std::size_t>(result.to_ulong()) << std::endl;
}

实际上应该返回与value相同的值,但出于某种原因,std::bitset版本的工作正常,而std::size_t的版本则不然。

这样很奇怪,因为AFAIK std::bitset,当出现错误时会抛出异常,而更多的AFAIK bitset应该与无符号整数上的操作行为相同,但正如我们所看到的,即使bitset有相同的位数它表现不一样。事实上,对我来说,std::bitset工作正常,而std::size_t却没有。

我的配置是: intel corei7 - g ++ - 5.4.0-r3

1 个答案:

答案 0 :(得分:1)

  

[expr.shift] / 1 ...如果右操作数为负数,或大于或等于长度,则[移位运算符 - IT]的行为未定义在升级左操作数的位中。

强调我的。 allBitsSet >> (maxBits - begin)(在非bitset版本中)表现出未定义的行为。

另一方面,bitset::operator>>的行为定义明确:allBitsSet >> (maxBits - begin)生成一个所有零位的bitset。