C ++中的Bit Field Struct to int

时间:2018-04-18 11:19:49

标签: c++ c++11 visual-c++ bit-fields reinterpret-cast

我有一个结构相同的类型成员。我正在尝试将其转换为uint8_t类型。我能做到但是看不到输出请告诉我哪里出错了。另外我知道还有其他办法吗?我试图这样做是因为我希望能够使用static_castreinterpret_cast

代码如下:

int main()
{
    struct xs{
        bool x :1 ;
        bool y :1;
        bool z :1;
        uint8_t num :5;
    } zs;

    uint8_t* P = static_cast<uint8_t*>(static_cast<void*>(&zs));

    cout << *P << endl;

    return 0;
}

3 个答案:

答案 0 :(得分:1)

这里有很多问题:

  1. 您似乎相信xyz都将打包成单uint_8。不是这种情况。 &#34;相邻类型的相邻声明的位字段 可以由编译器打包成数量减少的字数&#34; [1]
  2. &#34; sizeof(bool)的值是实现定义的,可能与1&#34; [2] 不同因此,您的xs将是实现定义的,但肯定不等同于sizeof(uint_8)
  3. 因为xs不是&#34;类似&#34;根据{{​​3}} uint_8reinterpret_cast<uint_8*>的行为未定义
  4. 最后the rules defined for C++'s type aliasing您无法看到任何内容的原因是,无论实现定义的值是*P,它都可能是一个控制字符,在{{1}处理时没有可见的表示形式}作为cout
  5. 您所拥有的代码的可能解决方法是使用这些定义:

    char

    然后假设某个值分配给constexpr uint8_t X = 0B1000'0000; constexpr uint8_t Y = 0B0100'0000; constexpr uint8_t Z = 0B0010'0000; constexpr uint8_t NUM = 0B0001'1111; uint8_t zs; ,您可以执行这些函数来输出以前的位字段:

    zs

    as has been pointed out by many others

答案 1 :(得分:0)

  1. 通过指向对象类型以外的类型的指针访问对象是未定义的行为。它适用于大多数编译器,但从技术上讲,您的程序可以做任何想做的事情。

  2. 假设我们没有遇到1中提到的问题,我的猜测是uint8_t是char的别名,所以cout会将char放到你的控制台上。 你没有初始化你正在检查的内存,所以它可以是0.一个值为零的char不会在你的控制台中打印出任何“可观察的”,看看ascii表。尝试使用50填充结构,例如

答案 2 :(得分:0)

这里有两件事需要解决。首先,正如一些人指出的那样,你无法以这种方式访问​​你的对象。如果你想正确构造一个uint8_t,你需要读取你的struct中的变量并进行一些位移,如下所示:

uint8_t value = 0;
value |= (zs.x ? 1 << 7 : 0);
value |= (zs.y ? 1 << 6 : 0);
value |= (zs.z ? 1 << 5 : 0);
value |= zs.num;

现在,您面临的第二个问题是您尝试输出8位宽的数字。默认情况下,这被解释为&#39;字符&#39;并将显示为这样。为了完成你想要做的事情,你可以使用不同长度的变量(uint16_t,uint32_t,...)或使用std :: to_string。

cout << std::to_string(value) << endl;