c++ - 位成员倒序?

标签 c++ linux g++

<分区>

我有以下代码:

#include <iostream>
#include <bitset>

#pragma pack(1)
typedef uint8_t flag_t;
typedef struct flag_struct_t {
        flag_t f1:1;
        flag_t f2:2;
        flag_t f3:2;
        flag_t f4:2;
        flag_t f5:1;
} flag_struct_t;


int main() {
    const uint8_t flagValue = 96;
    std::bitset<8> mybits(flagValue);
    const flag_struct_t flag = *reinterpret_cast<const flag_struct_t*>(&flagValue);
    std::cout << "f2 = " << (uint16_t)flag.f2 << std::endl;
    std::cout << "f3 = " << (uint16_t)flag.f3 << std::endl;
    std::cout << "f4 = " << (uint16_t)flag.f4 << std::endl;
    std::cout << "bitset = " << mybits << std::endl;
    std::cout << "size of flag_struct_t = " << sizeof(flag_struct_t) << std::endl;
}

#pragma pack()

输出是:

$ ./mybitset 
f2 = 0
f3 = 0
f4 = 3
bitset = 01100000
size of flag_struct_t = 1

似乎结构成员的顺序已从 f1, f2, f3, f4 反转为 f4, f3, f2, f1

这是为什么?

如果重要的话,我正在使用 GCC 8。

谢谢!

最佳答案

首先,由于通过 reinterpret_cast 进行的类型双关,您的程序具有未定义的行为。其次,位域的布局是实现定义的([class.bit]/1),因此无法保证位域的成员将如何分配。但是现在让我们假设编译器会非常好,并且实际上将其转换为执行您期望的代码。

十进制 96 的二进制表示形式是 01100000。请注意,数字通常是从右向左书写的(大概是因为它们起源于阿拉伯语)。例如,十进制数 123 中的“第一位”(最低有效位)将是 3,而不是 1。二进制也不异常(exception)。因此,如果我们假设编译器按照声明的顺序打包位域的成员,从第一位开始,那么布局应该如下所示

Bit  7  6  5  4  3  2  1  0  
    f5 f4 f4 f3 f3 f2 f2 f1

或者,对于您示例中使用的特定值

Bit  7  6  5  4  3  2  1  0  
     0  1  1  0  0  0  0  0

这正是你所看到的,如果我没记错的话......

关于c++ - 位成员倒序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55389262/

相关文章:

linux - 从 vpnbook.com 自动化 VPN 的 Bash 脚本

java - 我在我的盒子里部署 war 时遇到异常,它在另一个盒子里运行良好

c++ - 调用临时对象的方法安全吗?

c++ - 使用g++编译cpp文件时出错

c++ - CUDA内存错误

c++ - Stroustrup 书中的前后条件

c++ - 如何使用包含 std::thread 的 std::vector 的结构类型正确初始化 std::vector

python - 使用 boost::python,如何将结构 vector 作为字典列表返回给 Python?

php - SOAP 网络服务不仅仅适用于 IOS 设备,它适用于 soap ui 和 Android 设备

c++ - Linux g++编译错误: error: expected ',' or '...' before '||' token