简体   繁体   English

如何将 c 中的整数位字段连接成 uint64_t 整数?

[英]How can I concatenate integer bit fields in c into a uint64_t integer?

I have a struct in c like this我在 c 中有一个这样的结构

struct RegisterStruct
{
    uint64_t b_0 : 64;
    uint64_t b_1 : 64;
    uint64_t c_0 : 64;
    uint64_t c_1 : 64;
    uint64_t c_2 : 64;
    uint64_t d_0 : 64;
    uint64_t d_1 : 64;
};

I would like to concatenate the fields into an uint64_t integer.我想将字段连接成一个uint64_t整数。 Each of the fields should occupy a given number of bits defined as follows:每个字段应占用给定数量的位,定义如下:

b_0: 4bits 
b_1: 4bits
c_0: 8bits
c_1: 8bits
c_2: 8bits
d_1: 16bits
d_2: 16bits

The result should be an uint64_t integer containing the concatenated bit fields(from b_0 to d_2 ) each occupying the given number of bits.结果应该是一个uint64_t整数,其中包含连接的位字段(从b_0d_2 ),每个字段占用给定的位数。

Here is what I have tried but I don't think this solution is correct:这是我尝试过的,但我认为这个解决方案不正确:

struct RegisterStruct Register;

   Register.b_0 = 8;
   Register.b_1 = 8;
   Register.c_0 = 128;
   Register.c_1 = 128;
   Register.c_2 = 128;
   Register.d_0 = 32768;
   Register.d_1 = 32768;

   uint64_t reg_frame =Register.b_0<<60|Register.b_1<<56|Register.c_0<<48|Register.c_1<<40|Register.c_2<<32|Register.d_0<<16|Register.d_1;

You can put the structure containing the bit fields in a union with the full 64-bit unsigned integer like this:您可以将包含位字段的结构与完整的 64 位无符号整数放在一个联合中,如下所示:

union RegisterUnion
    struct
    {
        uint64_t b_0 : 4;
        uint64_t b_1 : 4;
        uint64_t c_0 : 8;
        uint64_t c_1 : 8;
        uint64_t c_2 : 8;
        uint64_t d_0 : 16;
        uint64_t d_1 : 16;
    };
    uint64_t val;
};

The main problem with the above is that it is not portable .上面的主要问题是它不便携 The C standard leaves the order in which bit fields are packed into their underlying storage unit type ( uint64_t in this case) as an implementation defined decision. C 标准将位字段打包到其底层存储单元类型(在本例中为uint64_t )的顺序作为实现定义的决定。 This is entirely separate from the ordering of bytes within a multi-byte integer, ie the little endian versus big endian byte ordering.这与多字节整数内的字节排序完全分开,即小端字节序与大端字节序。

In addition, using uint64_t as the base type of a bit-field might not be supported.此外,可能不支持使用uint64_t作为位字段的基本类型。 An implementation is only required to support bit-field members of types _Bool , signed int and unsigned int (or qualified versions thereof).一个实现只需要支持_Boolsigned intunsigned int (或其限定版本)类型的位域成员。 According to the C11 draft 6.7.2.1 paragraph 5 :根据C11 草案 6.7.2.1 第 5 段

  1. A bit-field shall have a type that is a qualified or unqualified version of _Bool , signed int , unsigned int , or some other implementation-defined type.位域的类型应为_Boolsigned intunsigned int或其他一些实现定义类型的限定或非限定版本。 It is implementation-defined whether atomic types are permitted.是否允许原子类型是实现定义的。
typedef union
{ 
    struct
    {
        uint64_t b_0 : 4;
        uint64_t b_1 : 4;
        uint64_t c_0 : 8;
        uint64_t c_1 : 8;
        uint64_t c_2 : 8;
        uint64_t d_0 : 16;
        uint64_t d_1 : 16;
    };
    uint64_t u64;
}R_t;


int main()
{

    R_t Register;

    Register.b_0 = 8;
    Register.b_1 = 8;
    Register.c_0 = 128;
    Register.c_1 = 128;
    Register.c_2 = 128;
    Register.d_0 = 32768;
    Register.d_1 = 32768;

    printf("%llx\n", (long long unsigned)Register.u64);
}

https://godbolt.org/z/_dYuz2 https://godbolt.org/z/_dYuz2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM